MySQL 事务
# 事务介绍
事务是一组操作的结合,是一个不可分隔的工作单位。事务会将其包含的多个操作一并提交给系统执行,这些操作要么全部成功,要么全部失败,不允许出现部分操作成功,部分操作失败的情况。
比如:张三给李四转账 1000 块钱,张三银行账户的钱减少 1000,而李四银行账户的钱要增加 1000。 这一组操作就必须在一个事务的范围内,要么都成功,要么都失败。不允许出现张三账户减少 1000,但是李四账户没有增加 1000。
提示
MySQL 事务都是指在 InnoDB 引擎下,MyISAM 引擎是不支持事务的。
# 事务四大特性
事务四大特性简称 ACID:
- 原子性(Atomicity):事务是不可分割的最小操作单元,要么全部成功,要么全部失败。
- 一致性(Consistency):事务完成时,必须使所有的数据都保持一致状态。
- 隔离性(Isolation):数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行。
- 持久性(Durability):事务一旦提交或回滚,它对数据库中的数据的改变就是永久的。
# 事务控制
# 查看事务提交方式
select @@autocommit;
1
结果为 1,表示自动提交;结果为 0 表示手动提交。
# 设置事务提交方式
set @@autocommit = 0; -- 设置为手动提交
set @@autocommit = 1; -- 设置为自动提交
1
2
2
# 开启事务
start transaction
1
# 提交事务
commit;
1
# 回滚事务
rollback
1
如:
-- 开启事务
start transaction
-- 张三账户减少1000
update table set money = money - 1000 where name = '张三';
-- 李四账户增加1000
update table set money = money + 1000 where name = '李四';
-- 执行正常,提交事务
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
# 并发事务问题
# 脏读
脏读指的是读到了其它事务未提交的数据,未提交意味着这些数据可能会回滚,也就是可能最终不会存到数据库中,也就是不存在的数据。读到了并一定最终存在的数据,这就是脏读。
# 不可重复读
不可重复读指的是在同一事务内,不同的时刻读到的同一批数据可能是不一样的,可能会受到其它事务的影响,比如其它事务改了这批数据并提交了。通常针对数据更新操作。
# 幻读
幻读是针对数据插入操作来说的。假设事务 A 对某些行的内容作了更改,但是还未提交,此时事务 B 插入了与事务 A 更改前的记录相同的记录行,并且在事务 A 提交之前先提交了,而这时,在事务 A 中查询,会发现好像刚刚的更改对于某些数据未起作用,但其实是事务 B 刚插入进来的,让用户感觉很魔幻,感觉出现了幻觉,这就叫幻读
# 事务隔离级别
事务隔离级别是为了解决并发事务引起的问题产生的,主要有以下几种:
- 读未提交(READ UNCOMMITTED)
- 读提交(READ COMMITTED)
- 可重复读(REPEATABLE READ)
- 串行化(Serializable)
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交 | √ | √ | √ |
读提交 | × | √ | √ |
可重复读 | × | × | √ |
串行化 | × | × | × |
总结:
- 默认隔离级别为可重复读
- 从上往下,隔离强度逐渐增强,性能逐渐变差
- 只有串行化解决了所有问题,其它三个都有缺陷
- 读未提交一个问题都没解决
上次更新: 2023/11/01, 03:11:44