- 事务是数据库管理系统(DBMS)中的一个概念,它确保了数据的正确性和可靠性,同时提供了并发控制和故障恢复的机制。
- 在操作上,事务是一种机制、一个操作序列,包含了一组数据库操作(如数据的读取、插入、更新或删除等)。这些操作可以是针对一个或多个数据对象(表、行、列等)的,这些操作要么都成功执行,要么都不执行。
- 如果其中一个操作失败,整个事务将被回滚,即所有操作都将被撤销,使数据库恢复到事务开始之前的状态。如果一个操作成功,则所有操作的结果都会被保存。
- 在逻辑上,事务是一个不可分割的工作逻辑单元,在数据库系统上执行并发操作时,事务是最小的控制单元
特性
- 事务具有以下四个特性,通常被称为 ACID 特性,ACID 是所有特性的缩写,是一系列操作组成事务的必要条件
事务特性 |
名称 |
说明 |
Atomicity |
原子性 |
事务中的所有操作要么全部执行成功,要么全部不执行。如果其中一个操作失败,整个事务将被回滚,保持数据库的一致性 |
Consistency |
一致性 |
事务的执行将数据库从一个一致的状态转换到另一个一致的状态。这意味着事务必须满足预定义的一致性规则,不会破坏数据库的完整性 |
Isolation |
隔离性 |
事务的执行是相互隔离的,每个事务都感知不到其他事务的存在。这意味着并发执行的多个事务之间不会相互干扰,保证了数据的正确性和可靠性 |
Durability |
持久性 |
一旦事务成功提交,其所做的修改将永久保存在数据库中,即使在系统故障或重启后也能够恢复 |
- 事务的使用可以确保数据库操作的完整性和可靠性,尤其在多用户并发访问的环境下非常重要
并发问题
- 数据库事务并发执行时,会存在以下读写问题
问题 |
名称 |
说明 |
Lost Update |
更新丢失 |
当两个事务同时更新同一条数据,最后只保留了其中一个事务的更新结果,造成另一个事务的更新丢失 |
Dirty Read |
脏读 |
一个事务读取了另一个事务还未提交的未合法数据 |
Non-Repeatable Read |
不可重复读 |
一个事务先后读取同一条记录,但读取结果不同。
例如另一个事务在两次读取之间更新了数据 |
Phantom Read |
幻读 |
一个事务按相同查询条件重新读取数据,但读取结果不同。
例如另一个事务在两次读取之间插入或删除了数据记录 |
- 更新丢失(Lost Update)分为以下两种情况
- 在第一类丢失更新(回滚覆盖)下,事务 A 和 B 先后对同一个值进行修改,后一个事务先提交,前一个事务回滚,导致后一个事务的更新丢失
- 在第二类丢失更新(提交覆盖)下,事务 A 和 B 先后对同一个值进行了修改,分别在不同时间提交,导致前一个事务的更新丢失
- 在发生脏读(Dirty Read)的情况下,事务 A 先对一个值进行修改,事务还未提交,此时事务 B 查询,读取到事务 A 修改的值。但最后事务 A 回滚,丢弃之前的修改,导致事务 B 读取的值无效
- 发生不可重复读(Non-Repeatable Read)的情况下,事务 B 先后执行两次查询,相关数据中途被事务 A 修改,导致两次查询读取的值不同
- 发生幻读(Phantom Read)的情况发生于数据的插入或删除状态下,其他事务的多次查询读取导致的问题
- 事务 B 先后执行两次查询,两次查询条件相同,相关数据中途被事务 A 删除了一条,导致后一次查询的结果集少了一条
- 事务 B 先后执行两次查询,两次查询条件相同,相关数据中途被事务 A 插入了一条,导致后一次查询的结果集多了一条
注
- 幻读(Phantom Read)和 不可重复读(Non-Repeatable Read)的主要区别是增加了查询条件,前者专注于结果集的变化,后者专注于单个结果的变化
隔离级别
- 隔离级别主要通过控制事务并发来防止事务之间的相互干扰和不一致,实现不同程度的并发控制,平衡一致性与性能。
隔离级别 |
名称 |
说明 |
Read Uncommited |
读未提交 |
一个事务可以读取另一个未提交事务的数据 |
Read Commited |
读已提交 |
一个事务只能读取另一个事务已经提交的数据,不能读取到未提交的数据 |
Repeatable Read |
可重复读 |
当前事务执行开始后,不允许其他事务对所读取数据的修改操作 |
Serializable |
可串行化 |
事务串行化顺序执行,后一个事务的执行必须等待前一个事务结束 |
- 对于事务的隔离性和并发性是相对的,隔离级别越高,并发性越弱,不同的事务的隔离级别,在为了在性能和数据安全的两者之间找一个平衡点
- 事务的隔离级别主要为了解决事务产生的并发问题
隔离级别 |
第一类丢失更新 |
第二类丢失更新 |
脏读 |
不可重复读 |
幻读 |
读未提交(Read Uncommited) |
不可能 |
可能 |
可能 |
可能 |
可能 |
读已提交(Read Commited) |
不可能 |
可能 |
不可能 |
可能 |
可能 |
可重复读(Repeatable Read) |
不可能 |
不可能 |
不可能 |
不可能 |
可能 |
可串行化(Serializable) |
不可能 |
不可能 |
不可能 |
不可能 |
不可能 |
注
- 可串行化(Serializable)是最高的事务隔离级别,在该级别下,事务串行化顺序执行,可以避免脏读、不可重复读与幻读。但是这种事务隔离级别效率低下,比较耗数据库性能,一般不使用