MySQL事务
# MySQL事务
# 1 事务的概念
事务是一逻辑上的一组操作,要么都执行,要么都不执行?
举一个例子:转账
假如小明要给小红转1000元,那么转账操作会设计以下两个操作:
1 小明余额减少1000元
2 小红余额增加1000元。
事务会把两个操作堪称逻辑上的一个整体,这个整体包含的操作要么都成功,要么都失败。不会出现小明余额减少,而小红余额却没有增加的情况。要保证数据库的一致性。
mysql开启事务操作
START TRANSACTION;
事务代码
COMMIT;
2
3
COMMIT
:更改永久保存到数据库中ROLLBACK
:回滚事物
在MySQL中,默认情况下,每个SQL语句都被视为一个单独的事务,即自动提交模式。如果你想手动控制事务,你需要显式地使用上述语句来开启、回滚和提交事务。
# 2 数据库事务
对于单体架构,没有特指分布式事务的话,那么指的就是数据库事务。
数据库事务可以保证多个对数据库的操作构成一个逻辑上的整体,构成这个逻辑上的整体的这些数据库操作遵循:要么全部执行成功,要么全部不执行。
# 3 MYSQL的隔离级别
- 读未提交(Read Uncommited,RU):事务A可以读取到事务B中未提交的数据。该隔离级别会导致脏读,不可重复读和幻读。
- 读已提交(Read Committed,RC):事务A可以读取到事务B已提交的数据。该隔离级别会导致不可重复读和幻读
- 可重复读(Repeatable Read,RR):事务A开启后,不管多久,事务A读取的数据都是一致的,即使事务B已经修改。该隔离级别会导致幻读。
- 串行化:效率低,解决所有问题;事务排队不能并发。
隔离级别 | 脏读(Dirty Read) | 不可重复读(NonRepeatable Read) | 幻读(Phantom Read) |
---|---|---|---|
未提交读(Read uncommitted) | ❌可能 | ❌可能 | ❌可能 |
已提交读(Read committed) | ✅不可能 | ❌可能 | ❌可能 |
可重复读(Repeatable read) | ✅不可能 | ✅不可能 | ❌可能 |
可串行化(Serializable ) | ✅不可能 | ✅不可能 | ✅不可能 |
MySQL的默认隔离级别是可重复读(REPEATABLE READ)
# 4 并发事务造成的问题
脏读(Dirty read):事务 A 读取到事务 B 中未提交的数据
丢失修改(Lost to modify):事务 A 修改数据的同时,事务 B 也修改数据,事务 A 提交数据后,事务 B 也提交数据,事务 B 修改的数据会将数据 A 给覆盖。
不可重复读(Unrepeatable read):事务A开启后,读取小明 15岁,此时开启事务B对小明年龄进行修改,事务A再次读取小明年龄为 18。该条数据修改导致的。
幻读(Phantom read):与不可重复的类似,读取的数据可能为 3 条。此时开启事务 B 增删数据并提交,事务A再次读取数据为 2 或 4 条,出现前后不一致的现象。该条数据周围及周围数据插入、删除导致的。
解决幻读的方法:
- 快照读:执行普通的 select,使用 MVCC 解决不可重复读、幻读的问题。不加锁,读取历史版本。
- 当前读:执行
select...for update/lock in share mode、insert、update、delete
,使用 Next-key Lock 解决幻读问题。加锁,读取当前版本,阻止其他事务插入数据。
不可重复读和幻读区别 :不可重复读的重点是修改比如多次读取一条记录发现其中某些列的值被修改,幻读的重点在于新增或者删除比如多次查询同一条查询语句(DQL)时,记录发现记录增多或减少了。
# 5 事务的4个特性ACID
- A:原子性(Atomicity):事务是最小的执行单位,不可分割。要么全部完成,要么全部不起作用。
- C:一致性(Consistency):在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设约束、触发器、级联回滚等。
- I:隔离性(Isolation):多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
- D:持久化(Durability):⼀个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响
# 6 事务可以嵌套吗
可以,因为嵌套事务可以是总舵事务分类中的一种,它是一个层次结构框架。有一个顶层事务控制着各个层次的事务,顶层事务之下嵌套的事务被称为子事务,它控制每一个局部的变换。
MYSQL数据库不支持嵌套事务。
# 7 四种隔离级别的具体实现
- 读未提交:什么都不做
- 序列化:无论做什么都加锁
- 读已提交 & 可重复读:通过多版本并发控制 MVCC 实现