脏读、不可重复读、幻读

参考:https://blog.****.net/baidu_35103892/article/details/82915692

一、脏读

1、概念

  • 脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另外一个事务读到的这个数据是脏数据,依据脏数据所做的操作可能是不正确的。

2、示例:

1)如下图:
脏读、不可重复读、幻读
2)示例解释:

  • 例如上图示例中,事务A将某一值修改,然后事务B读取该值,此后A因为某种原因撤销对该值的修改,这就导致了B所读取到的数据是无效的,值得注意的是,脏读一般是针对于update操作的。

二、不可重复读

1、概念:

  • 不可重复读,是指在数据库访问中,一个事务范围内两个相同的查询却返回了不同数据。
  • 一种更易理解的说法是:在一个事务内,多次读同一个数据。在这个事务还没有结束时,另一个事务也访问该同一数据并修改数据。那么,在第一个事务的两次读数据之间。由于另一个事务的修改,那么第一个事务两次读到的数据可能不一样,这样就发生了在一个事务内两次读到的数据是不一样的,因此称为不可重复读,即原始读取不可重复。

2、示例:

1)如下图:
脏读、不可重复读、幻读
2)示例解释:

  • 例如上图示例中,事务A读取某一数据,事务B读取并修改了该数据,A为了对读取值进行检验而再次读取该数据,便得到了不同的结果。

三、幻读

1、概念:

  • 幻读是指当事务不是独立执行时发生的一种现象。
  • 事务A读取与搜索条件相匹配的若干行。事务B以插入或删除行等方式来修改事务A的结果集,然后再提交。

2、示例:

1)如下图:
脏读、不可重复读、幻读

2)示例解释:

  • 幻读一般发生在计算统计数据的事务中,例如上图示例中,事务A中两次统计存款账户的总金额,在两次统计中,刚好新增了一个存款账户,事务B存入100元,这时候两次统计的总金额不一致。

四、不可重复读和幻读的区别

  • 不可重复读:指读到了已经提交的事务的更改数据(修改或删除),
  • 幻读:读到了其他已经提交事务的新增数据。

五、不可重复读和幻读的解决方式

  • 不可重复读:对操作的数据添加行级锁,防止操作中的数据发生变化
  • 幻读:需要添加表级锁,将整张表锁定,防止新增数据(oracle采用多版本数据的方式实现)

六、总结

  • 脏读:事务 A 读取了事务 B 未提交的数据,并在这个基础上又做了其他操作。
  • 不可重复读:事务 A 读取了事务 B 已提交的更改数据。
  • 幻读:事务 A 读取了事务 B 已提交的新增数据

第一条是坚决抵制的,后两条在大多数情况下可不作考虑。