目录
1 概述
MySQL的事务是默认是自动提交的,也就是说,当执行一条DML语句,MySQL会立即隐式的提交事务
2 事务操作
方式一
查看/设置事务提交方式
- select @@autocommit
- set @@autocommit=0; (1:自动提交 2:手动)
提交事务
commit
回滚事务(在执行操作时,出现异常)
rollback
方式二
开启事务
start transaction或begin
提交事务
commit
回滚事务(在执行操作时,出现异常)
rollback
3 事务四大特性
4 并发事务问题
脏读:一个事务读取到另一个事务还没有提交的数据
- 如:事务A在修改数据时,修改结束,但未提交事务,此时事务B查询到了事务A修改后但未提交的内容
不可重复读:一个事务先后读取同一条记录,但两次读取的数据不同,称之为不可重复读
如:在事务A中,事务A先去查询了一条数据,比如money=100,事务B区修改了这条数据money-100,事务A又去查询了一次数据,发现此时money=0,在一次事务中,因为并发的出现先后查询出了两次不一样的结果
可重复读就是,在一个事务中,相同的SQL要查到相同的数据
幻读:一个事务按照条件查询时,没有对应的数据行,但是在插入数据时,又发现这行数据已经存在,好像出现了“幻影”
幻读已经解决了不可重复读的问题,在读取时不会读取其它事务已经改变的结果
5 事务隔离级别
5.1 隔离级别
5.2 幻读的两种场景
- 在读未提交和读已提交隔离级别下,出现查询的两次结果集不一样,会出现不可重复读问题
- 而在可重复读隔离机制下,不会出现查询结果不一样,因为每次查询都是从事务开始的快照查询的,但会出现查询数据不存在,而插入数据时出现重复问题
在 可重复读 隔离级别下,事务 A 在开始时会创建一个快照。此快照会在整个事务过程中保持一致。因此,事务 A 在其生命周期内的所有查询都会返回相同的结果集。
为什么会出现查不到数据但又无法插入:
- 当事务 B 提交数据后,事务 A 仍然无法看到这些数据,因为它的快照未更新。
- 但是,在事务 A 尝试插入与事务 B 相同的 ID 的数据时,数据库会检查当前的实际数据状态(包括已提交的事务),发现该 ID 已经存在,从而拒绝插入。
- 所以,读的时候查询事务开始时的快照,相同SQL查询的结果一致,确保了可重复读