前言
事务概念及特性
事务是指数据库操作的一个逻辑单位,它由一组被视为一个整体的数据库操作组成。
事务具有以下特性:
- 原子性(Atomicity):事务中的所有操作要么全部成功执行,要么全部失败回滚。如果事务中的任何一部分操作失败,则将回滚到事务开始前的状态,之前已完成的操作会被撤销,数据库不会受到破坏。
- 一致性(Consistency):事务执行前后,数据库应该保持一致的状态。这意味着在事务开始前和结束后,数据库中的数据应满足所有的约束、触发器和其他规定的业务规则。
- 隔离性(Isolation):多个事务可以并发地执行,每个事务都认为自己在独立地操作数据,而不会受到其他事务的影响。隔离性确保了事务之间的数据相互隔离,避免并发执行时可能导致的问题,如脏读(读取到未提交的数据)、不可重复读(同一事务内两次读取到的数据不一致)和幻读(同一查询多次执行结果不一致)等。
- 持久性(Durability):一旦事务成功提交,其所做的修改将永久保存在数据库中,并在系统故障或重启后仍然存在。
事务管理
开启事务
在MySQL中默认DML执行的请求是自动提交的,开启事务就是关闭自动提交。
使用以下语句开启事务:
start transaction;
回滚事务
如果在事务执行过程中发生了错误,可以使用以下语句回滚事务:
rollback;
提交事务
无错误,执行以下语句提交事务:
commit;
事务隔离级别
MySQL数据库支持多个事务隔离级别,用于控制并发事务之间的隔离程度。以下是MySQL中常见的四个事务隔离级别:
- 读未提交(Read Uncommitted):最低的隔离级别,在该级别下,一个事务可以读取到另一个事务尚未提交的数据变更。这种隔离级别可能导致脏读、不可重复读和幻读的问题。
- 读已提交(Read Committed):在该隔离级别下,一个事务只能读取到已经提交的数据变更。但是,由于并发操作可能导致其他事务的数据变更,可能会出现不可重复读和幻读的问题。
- 可重复读(Repeatable Read):该隔离级别确保了同一事务中多次执行相同的查询都将获得相同的结果,即使其他事务对数据进行了修改。但是,仍然存在幻读的问题,即同一查询多次执行时结果集不一致。
- 串行化(Serializable):最高的隔离级别,通过强制事务串行执行来避免并发问题。它会对所有读取的行加锁,从而完全消除脏读、不可重复读和幻读的问题。但是,串行化级别可能会降低系统的并发性能。
其中,
- 脏读(Dirty Read):脏读指的是一个事务读取了另一个事务尚未提交的数据。当一个事务对数据进行修改但未提交时,其他事务可能会读取到这个未提交的数据,如果修改后的数据被回滚,那么读取到的数据就是无效的或错误的,这就是脏读的情况。
- 不可重复读(Non-repeatable Read):不可重复读指的是在同一个事务中,多次执行相同的查询,但在期间其他事务对数据进行了修改,导致每次查询得到的结果不一致。也就是说,一个事务内部两次读取同一数据的结果不一样,这种情况下称为不可重复读。
- 幻读(Phantom Read):幻读指的是在同一个事务中,多次执行相同的查询,但在期间其他事务插入或删除了符合查询条件的数据,导致每次查询得到的结果集不一致。换句话说,第一次查询返回某些行,然后在事务进行的过程中,有新的行满足了前面的查询条件,再次查询时将出现"幻觉"般的新增行,这就是幻读的情况。
隔离级别 | 脏读 | 不可重复读(虚读) | 幻读 |
---|---|---|---|
Read Uncommitted 读未提交 | ✔️ | ✔️ | ✔️ |
Read Committed 读已提交 | ✖️ | ✔️ | ✔️ |
Repeatable Read 可重复读 | ✖️ | ✖️ | ✔️ |
Serializable 串行化 | ✖️ | ✖️ | ✖️ |
设置隔离级别
MySQL的默认隔离级别是可重复读。可以使用以下语句设置事务的隔离级别:
set transaction isolation level <isolation level>;
其中,isolation level 可以是上述四个隔离级别之一。