一、事务特性:
首先,事务应该具有 4 个属性:原子性、一致性、隔离性、持久性。这四个属性通常称为 ACID 特性。
原子性(atomicity):意味数据库中的事物执行是作为原子粒度,既不可在分,整个语句要么执 行要么不执行
一致性(consistency):即在事物开始之前和事物结束以后,数据库的完整性约束没有被破坏
隔离性(isolation):事物的执行是互不干扰的,一个事务不可能看到其他的事物运行时,中间某 一时刻的数据
持久性(durability):意味着在事物完成以后,该事物所对数据库所作的更改便持久的保存在数 据库中,不会被回滚
二、隔离性(isolation)详解:
1、隔离级别:
一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。(对数据库的并行执行,应该像串行执行一样)
未提交读(READ UNCOMMITED)脏读
已提交读 ( READ COMMITED )脏读,脏写
可重复读( REPEATABLE READ )脏读,脏写,不可重复读,幻读(如果是mysql的innodb 则以解决)
可串行化( SERIALIZABLE )脏读,脏写,不可重复读,幻读
数据库的事务隔离级别有四种,分别是读未提交、读已提交、可重复读、序列化,不同的隔离级别下会产生脏读、幻读、不可重复读等相关问题,因此在选择隔离级别的时候要根据应用场景来决定,使用合适的隔离级别。各种隔离级别和数据库异常情况对应情况如下:
mysql 默认的事务隔离级别为: 可重复读(REPEATABLE READ)
2、SQL 标准定义了四个隔离级别:
- READ-UNCOMMITTED(读取未提交): 事务的修改,即使没有提交,对其他事务也都是可见的。事务能够读取未提交的数据,这种情况称为脏读。
- READ-COMMITTED(读取已提交): 事务读取已提交的数据,大多数数据库的默认隔离级别。当一个事务在执行过程中,数据被另外一个事务修改,造成本次事务前后读取的信息不一 样,这种情况称为不可重复读。
- REPEATABLE-READ(可重复读): 这个级别是MySQL的默认隔离级别,它解决了脏读的问题,同时也保证了同一个事务多次读取同样的记录是一致的,但这个级别还是会出现幻读的 情况。幻读是指当一个事务A读取某一个范围的数据时,另一个事务B在这个范围插入行,A事务再次读取这个范围的数据时,会产生幻读。
- SERIALIZABLE(可串行化): 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重 复读以及幻读。
三、事务并发问题
脏读:事务 A 读取了事务 B 更新的数据,然后 B 回滚操作,那么 A 读取到的数据是脏数据。
不可重复读:事务 A 多次读取同一数据,事务 B 在事务 A 多次读取的过程中,对数据作了更新并提交,导致事务 A 多次读取同一数据时,结果 不一致。
幻读:系统管理员 A 将数据库中所有学生的成绩从具体分数改为 ABCDE 等级,但是系统管理员 B 就在这个时候插入了一条具体分数的记录,当系统管理员 A 改结束后发现
还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。(事务A按照一定条件进行数据读取,期间事务B插入了相同搜索条件的新数据,事务A再次按照原先条件进行修改数据,发现修改了事物B刚才提交的数据,而且再次读取时,发现了事务B新插入的数据称之为幻读。)
不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件就行,解决幻读需要锁表(当前读和快照读共同参与时才可能发生幻读)。