事务
# 事务
事务:一条或者多条 SQL 语句组成一个执行单元,特点是要么同时成功要么同时失败,每条语句都相互依赖,形成一个整体,如果失败或者出现错误,那么状态会撤回到事务最初状态 (回退)
- 开启事务 start transaction; 开启事务后所有的操作都是虚拟化的
- 回滚事务 rollback; 结束事务并回退
- 提交事务 commit; 结束事务并提交
# 提交方式
-- 查看数据库事务默认提交方式
SHOW VARIABLES LIKE 'autocommit'; -- ON为自动提交 OFF手动提交
select @@autocommit; -- 1为自动提交 0为手动添加
-- 修改事务的提交方式
SET autocommit = OFF;
-- 手动开启一个事务
START TRANSACTION;
-- 或
BEGIN;
-- 提交事务
COMMIT;
-- 回滚事务
ROLLBACK;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
如果修改为手动提交 不开始事务 做增删改查 操作也需要 commit 操作才生效
# 事务的四大特征 (ACID)
- 原子性(Atomicity)
- 指事务包含的所有操作要么全部成功,要么全部失败回滚 因此事务的操作成功则要应用到数据,操作失败则不能对数据库有影响
- 一致性 (Consistency)
- 一致性指事务必须使数据库从一个一致性变化到另外一个一致性 也就是说一个事务执行之前和执行之后都必须处于一个一致性
- 隔离性(isolcation)
- 隔离性是当多个用户并发访问数据库时,如操作同一张表时,数据库为每个用户开启事务 不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。
- 持久性(durability)
- 持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的 即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作
# 事务的状态
- 活动的 (active):事务对应的数据库操作正在执行过程中时,即为该事务处在活动的状态。
- 部分提交的 (partially committed):当事务中的最后一个操作执行完成,但由于操作都在内存中执行,所造成的影响并没有刷新到磁盘时,即为该事务处在部分提交的状态。
- 失败的 (failed):当事务处在活动的或者部分提交的状态时,可能遇到了某些错误(数据库自身的错误、操作系统错误或者直接断电等)而无法继续执行,或者人为地停止当前事务的执行,即为该事务处在失败的状态。
- 中止的 (aborted):如果事务执行了一部分而变为失败的状态,那么就需要把已经修改的事务中的操作还原到事务执行前的状态。换句话说,就是要撤销失败事务对当前数据库造成的影响。把这个撤销的过程称之为回滚。当回滚操作执行完毕时,也就是数据库恢复到了执行事务之前的状态,称之为该事务处在了中止的状态。
- 提交的 (committed):当一个处在部分提交的状态的事务将修改过的数据都同步到磁盘上之后,即为该事务处在了提交的状态。
事务状态流程如下图

# 事务的隔离性级别
- READ UNCOMMITTED(读未提交):允许事务读取未被其他事务提交的变更。脏读、不可重复读和幻读的问题都会出现。
- READ COMMITTED(读已提交):只允许事务读取已经被其他事务提交的变更。可以避免脏读,但不可重复读和幻读的问题仍然可能出现。
- REPEATABLE READ (可重复读):确保事务可以多次从一个字段中读取相同的值,在这个事务持续期间,禁止其他事务对这个字段进行更新。可以避免脏读和不可重复读,但幻读仍然存在。
- SERIALIZABLE (可串行化):确保事务可以从一个表中读取相同的行,在这个事务持续期间,禁止其他事务对该表执行插入、更新和删除操作,所有并发问题都可避免,但性能十分低下。因能避免脏读、不可重复读和幻读。

# 引发的问题
- 脏写 (Dirty Write):对于两个事务 Session A 、 Session B ,如果事务 Session A 修改了另一个未提交事务 Session B 修改过的数据,那就意味着发生了脏写。
- 脏读:指的事务未被提交 另外一个事务已经可以查询到该事务的数据
- 不可重复读:指两个事务开启 其中一个事务已经提交了 另外一个事务读取到该事务的数据 正常来说应该是读取不到的,需要结束事务后才能读取
- 幻读:指查询某个数据不存在 但插入时无法无插入此数据,并且之后发现数据已经存在表中 或 某数据不存在 但执行删除操作 缺成功了

-- 查询数据库隔离级别
select @@TX_ISOLATION;
SHOW VARIABLES LIKE 'transaction_isolation';
-- 修改数据库隔离级别
set global|SESSION transaction isolation level 级别; -- 修改后需要重新连接数据库,REPEATABLE READ 为默认级别
1
2
3
4
5
2
3
4
5

编辑 (opens new window)
上次更新: 2023/12/13, 06:06:02