即当前事务(A)中可以读到其他事务(B)未提交的数据(脏数据)。
A事务读取B事务尚未提交的数据,此时如果B事务发生错误并执行回滚,那么A事务读取到的数据就是脏数据
这种情况经常发生于转账与取款操作中
即在事务A中按照某个条件先后两次统计数据库记录数,两次统计结果的记录数不同。
事务A在执行读取操作,需要两次统计数据的总量,前一次查询数据总量后,此时事务B执行了新增数据操作并执行了提交;这个时候事务A读取的数据总量和之前统计的不一样,平白无故的多了几条数据
即在事务A中先后两次读取同一个数据,两次读取的结果不一样。
- 事务A在执行读取操作,由于整个事务A较大,前后读取同一条数据需要经历很长的时间;
- 事务A第一次读取数据,事务B执行修改操作,然后事务A第二次读取到的数据与第一次不同,即数据不重复了
读取前后事务A还未结束,即在同一个事务中,事务A前后几次读取的数据不一致
不可重复读是读取了其他事务更改的数据,针对update
操作(某一条数据记录变了)
解决:使用行级锁
幻读是读取了其他事务新增的数据,针对insert
和delete
操作(数据记录数变了)
解决:使用表级锁
Atomicity
):一个事务是一个不可分割的工作单位,包含的操作要么全部成功,要么全部失败Consistency
):事务执行结束后,数据库的完整性约束没有被破坏,事务执行的前后都是合法的数据状态Isolation
):事务内部的操作与其他事务是隔离的,并发执行的各个事务之间不能互相干扰Durability
):事务一旦提交,它对数据库的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响Read uncommitted
、Read committed
、Repeatable read
、Serializable
,这四个级别可以逐个解决脏读 、不可重复读 、幻读 这几类问题Read uncommitted
并发可能导致很多问题,且性能提高有限,使用很少;Serializable
强制事务串行,并发效率很低,只有对数据一致性要求极高且可接受没有并发时使用Read committed
(Oracle)或Repeatable read
(简称RR
)InnoDB
默认隔离级别是RR
SQL
标准中,RR
是无法避免幻读的,但InnoDB
实现的RR
避免了幻读)参考资料: