概述

数据库中的事务有四大特性(ACID),分别是原子性、一致性、隔离性和持久性。针对隔离性,还有四个隔离级别,分别是串行化、可重复读、读已提交和读未提交。这四个隔离级别是针对并发事务中存在的三个问题,分别是脏读、不可重复读和幻读。


事务的四大特性

1. 原子性(Atomicity)

事务包含的所有数据库操作要么全部成功,要不全部失败回滚。

2. 一致性(Consistency)

一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。一致性规定事务提交前后只存在两个状态,提交前的状态和提交后的状态,绝对不会出现中间的状态。最典型的例子就是银行转账,A和B之间互相转账,账面加起来总和5000元,无论A和B之间怎么转,转几次,成功与否,事务结束后A和B账面总和还是5000元。

3. 隔离性(Isolation)

隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰多个并发事务之间要相互隔离。即要达到这么一种效果:对于任意两个并发的事务T1和T2,在事务T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后才开始,这样每个事务都感觉不到有其他事务在并发地执行。

4. 持久性(Durability)

持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。


事务并发时存在的问题

1. 脏读(Dirty Read)

脏数据所指的就是未提交的数据,而脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。比如,一个事务正在对一条记录做修改,在这个事务完成并提交之前,这条数据是处于待定状态的(可能提交也可能回滚),这时,第二个事务来读取这条没有提交的数据,并据此做进一步的处理,就会产生未提交的数据依赖关系。这种现象被称为脏读。

2. 不可重复读(Non-repeatable Read)

一个事务先后读取同一条记录,而事务在两次读取之间该数据被其它事务所修改,则两次读取的数据不同,我们称之为不可重复读。例如事务T1在读取某一数据,而事务T2立马修改了这个数据并且提交事务给数据库,事务T1再次读取该数据就得到了不同的结果,发送了不可重复读。

不可重复读和脏读的区别:脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是在同一事务内读取了前一事务提交的数据,即前一次读到的数据是另一个事务提交前,后一次读到的数据是提交后的。

3. 幻读(Phantom Read)

一个事务按相同的查询条件重新读取以前检索过的数据,却发现其他事务插入了满足其查询条件的新数据,这种现象就称为幻读。幻读是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,比如这种修改涉及到表中的“全部数据行”。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入“一行新数据”。那么,以后就会发生操作第一个事务的用户发现表中还存在没有修改的数据行,就好象发生了幻觉一样。

幻读和不可重复读都是读取了另一条已经提交的事务(这点就脏读不同),所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体(比如数据的个数)。

在实际开发和使用中,其实幻读问题是可以接受也符合用户的心理预期,比如在淘宝双十一抢东西,点击“购买”,成功进入**“下单页面”,结果到“付款页面”**却提示已经被抢完,这是可以接受的。


四个隔离级别

1. 读未提交(Read uncommitted)

所有事务都可以看到其他未提交事务的执行结果。本隔离级别是最低的隔离级别,虽然拥有超高的并发处理能力很低的系统开销,但很少用于实际应用。因为采用这种隔离级别只能防止更新丢失问题(这个问题现代关系型数据库已经不会发生),不能解决脏读,不可重复读及幻读问题。

2. 读已提交(Read committed)

这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这种隔离级别可以防止脏读问题,但会出现不可重复读幻读问题。

3. 可重复读(Repeatable read)

这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。这种隔离级别可以防止除幻读外的其他问题。

4. 串行化(Serializable )

这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读、第二类更新丢失问题。在这个级别,可以解决上面提到的所有并发问题,但可能导致大量的超时现象和锁竞争,通常数据库不会用这个隔离级别,我们需要其他的机制来解决这些问题:乐观锁和悲观锁。

在这里插入图片描述

参考

  1. 数据库事务的四大特性以及事务的隔离级别
  2. 数据库脏读、事务的四大特性、四大隔离级别、三大范式
  3. 数据库事务的四大特性(ACID)
  4. 仅此一文让你明白事务隔离级别、脏读、不可重复读、幻读
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐