事务的4个特性和4个隔离级别
- 1. 什么是事务
- 2. 事务的ACID特性
- 2.1 原子性
- 2.2 一致性
- 2.3 持久性
- 2.4 隔离性
- 3. 事务的创建
- 4. 事务并发时出现的问题
- 4.1 DIRTY READ 脏读
- 4.2 NON - REPEATABLR READ 不可重复读
- 4.3 PHANTOM READ 幻读
- 5. 事务的隔离级别
- 5.1 READ UNCOMMITTED 读未提交
- 5.2 READ COMMITTD 读已提交
- 5.3 REPEATABLE 可重复读
- 5.4 SERIALIZABLE 串行化
1. 什么是事务
事务,简单来说,就是将一组SQL语句组合成一个逻辑单元,这些语句要么全部成功执行,使数据库状态发生预期的改变;要么全部失败,数据库回滚到事务开始前的状态,仿佛这组操作从未发生过。
以日常生活中的转账场景为例,当A向B转账100元时,“A账户减少100元”和“B账户增加100元”这两个操作必须作为一个整体来执行,要么都成功完成转账,要么因为任何原因(如余额不足、网络故障等)都不执行,以保证资金的准确性和一致性。这,就是一个典型的事务。

2. 事务的ACID特性
事务之所以能可靠地管理数据,离不开其具有的四大特性:原子性(Atomicity)、一致性(Consistency)、持久性(Durability)和隔离性(Isolation),简称为ACID特性。
2.1 原子性
原子性确保事务是一个不可分割的最小工作单元。就像化学反应中的原子一样,事务中的所有操作要么一起成功,将数据持久化到数据库;要么一起失败,数据库状态回滚到事务开始之前,不会出现部分操作成功、部分操作失败的中间状态。
2.2 一致性
一致性要求事务执行前后,数据库的完整性约束没有被破坏,数据必须符合业务逻辑和预先设定的规则。例如,在转账事务中,转账前后的账户总金额应该保持不变,这是保证数据一致性的基本体现。
2.3 持久性
一旦事务被成功提交,其所做的修改就会永久性地保存在数据库中。即使后续系统发生故障,如硬件损坏、软件崩溃或断电等,已提交的数据也不会丢失,确保了数据的可靠性和稳定性。
2.4 隔离性
隔离性使得多个并发事务在执行时,相互之间不会产生干扰,每个事务都像是在独立运行。不同的隔离级别决定了事务之间的隔离程度,以及可能出现的并发问题,这将在后续详细讨论。
3. 事务的创建
在SQL语言中,我们可以通过以下语句来灵活地控制事务:
-- 开启一个新的事务,两种方式均可
START TRANSACTION;
-- 或者
BEGIN;
-- 当事务中的所有操作都顺利完成,使用此语句提交事务,将修改永久保存到数据库
COMMIT;
-- 如果在事务执行过程中出现错误或需要回滚操作,执行此语句取消已执行的所有修改
ROLLBACK;
4. 事务并发时出现的问题
当多个事务同时并发执行时,由于事务之间的相互影响,可能会出现以下几种常见的问题:
4.1 DIRTY READ 脏读
脏读是指一个事务读取到了另一个事务尚未提交的数据。如果未提交事务随后回滚,那么读取到的数据就是无效的,这可能导致数据的不一致和错误的业务决策。

4.2 NON - REPEATABLR READ 不可重复读
不可重复读是指在同一个事务中,多次读取同一数据时,由于其他事务在期间对数据进行了修改并提交,导致每次读取的结果不一致。这会给需要在事务中多次读取相同数据进行业务处理的场景带来困扰。

4.3 PHANTOM READ 幻读
幻读是指一个事务在执行过程中,发现另一个事务插入了新的数据,导致该事务再次读取数据时,出现了之前不存在的记录,仿佛产生了“幻觉”。例如在电商下单场景中,用户点击立即购买成功进入下单页面,准备付款时却显示库存不足,这就是幻读的一个典型例子。


5. 事务的隔离级别
为了解决事务并发执行时出现的上述问题,数据库提供了不同的隔离级别,每个隔离级别对并发事务的处理方式和所能避免的问题各不相同。常见的隔离级别有以下4种:
5.1 READ UNCOMMITTED 读未提交
这是最低的隔离级别,允许一个事务读取另一个事务尚未提交的数据。由于此级别几乎没有任何隔离措施,所以可能会出现脏读、不可重复读和幻读等各种并发问题,在实际应用中较少使用。
5.2 READ COMMITTD 读已提交
大多数数据库系统的默认隔离级别。在该级别下,一个事务只能读取其他事务已经提交的数据,可以有效避免脏读问题,但仍然可能出现不可重复读和幻读。
5.3 REPEATABLE 可重复读
MySQL的默认隔离级别。在此级别下,同一个事务内多次读取相同数据时,数据保持一致,能够避免脏读和不可重复读。然而,对于幻读问题,虽然在一定程度上得到了缓解,但并不能完全杜绝。
5.4 SERIALIZABLE 串行化
这是最高的隔离级别,事务会按照顺序依次执行,完全避免了脏读、不可重复读和幻读等所有并发问题。但由于事务串行执行,并发性能较低,适用于对数据一致性要求极高、并发量较低的场景。
通过下面的图片,可以更直观地了解不同隔离级别与并发问题之间的关系:

理解事务的概念、特性、操作以及并发问题和隔离级别,对于开发高效、可靠的数据库应用至关重要。在实际项目中,我们需要根据业务需求和系统性能要求,合理选择事务的隔离级别,以平衡数据一致性和并发性能之间的关系。