Mysql事务并发问题与隔离级别深入解析
本文目录
事务基础
事务控制语句
事务并发问题
脏读
不可重复读
幻读
第一类丢失更新(回滚丢失)
第二类丢失更新(逻辑丢失)
用隔离级别来解决并发问题
事务基础
事务四大特性ACID:
原子性
一致性
隔离性
持久性
扁平事务:最常用的;
带有保存点的扁平事务:可以回滚到某一个保存的,而不是回滚到事务最开始的地方;
链事务;
嵌套事务:Mysql不支持,如果有多个begin语句,则后面的begin会隐式提交;
分布式事务;
隔离性:锁
原子性、持久性:redo log
一致性:undo log
在循环中提交事务
使用自动提交
使用自动回滚
执行时间比较长的事务,可以转化为小批量事务来处理。
begin
start transaction
commit
rollback
比如create table类的ddl语句,这类语句有很多,在次不一一列举。
show global status like 'com_commit';
show variables like '%autocommit%';
read uncommitted
read committed
repeatable read
serializable
set global transaction isolation level 隔离级别
set session transaction isolation level 隔离级别
select @@tx_isolation
select @@global.tx_isolation
现在有一行数据,某个字段值为200
事务A开启事务
事务B开始事务
事务A将200修改为300,并提交
事务B将200修改为100,但事务B回滚,回滚之后变为200
事务A开启事务,并修改了一行数据;
事务B开启事务,修改了同一行数据;
事务A提交;
事务B提交;
事务A开启事务,读取了一行数据,假设该行数据有一个age字段,且age=10;
事务B开启了事务,读取了同一行数据,即age=10。
事务A进行修改操作,使新age=原age+10,然后提交。
事务B进行修改操作,使新age=原age+20,注意原age,事务B使用的是自己一开始读取的10,而不是事务A提交后的20,因此修改后的age=30,然后提交;
将隔离级别设为序列化读;
对读取操作上排它锁,select ... for update;
事务并发问题 |
事务隔离级别 |
第一类更新丢失 |
|
读未提交 |
|
脏读 |
|
读已提交(MVCC:读最新版本,因此造成了不可重复读) |
|
不可重复读 |
|
幻读 |
|
可重复读(MVCC:读旧版本;next-key Locking解决幻读) |
|
第二类丢失更新 |
|
序列化读 |