事务与ACID属性
- 原子性(Atomicity)
- 一致性(Consistency)
- 隔离性(Isolation)
- 持久性(Durable)
并发事务处理带来的问题
- 更新丢失:两个事务同时操作相同的数据,后提交的事务会覆盖先提交的事务的处理结果,通过乐观锁可以解决
- 脏读:事务A读取了事务B已经修改但是没有提交的数据,如果B事务回滚,那么A读取的数据无效,不符合一致性
- 不可重复读:事务A读取到了事务B已经提交的修改数据,不符合隔离性
- 幻读:事务A读取到了事务B提交的新增数据,不符合隔离性
隔离级别
mysql中的隔离级别
隔离级别 | 脏读(Dirty Read) | 不可重复读(NonRepeatable Read) | 幻读(Phantom Read) |
---|---|---|---|
(读未提交) read uncommited | 可能 | 可能 | 可能 |
(读已提交)read commited | 不可能 | 可能 | 可能 |
(可重复读)repeatable read | 不可能 | 不可能 | 可能 |
(可串行化)serializable | 不可能 | 不可能 | 不可能 |
查看当前隔离级别信息
mysql8.0将tx_isolation改成transaction_isolation
图片.png
实操
1、脏读问题及解决
这个时候需要将Mysql中的隔离级别设置为:Read Uncommited
set session transaction isolation level read committed;
mysql> show variables like 'transaction_isolation';
+-----------------------+----------------+
| Variable_name | Value |
+-----------------------+----------------+
| transaction_isolation | READ-COMMITTED |
+-----------------------+----------------+
1 row in set, 1 warning (0.00 sec)
- Innodb行锁
innodb会给更新语句加上行锁
图片.png
- 将当前会话的的事务的隔离级别设置为Read Uncommitted
以下设置的是Read Committed,相关设置类似
图片.png
- 脏读问题出现
脏读
图片.png
- 脏读问题解决
将隔离级别设置为Read Committed;
2、不可重复读问题及解决
先将隔离级别设置为:Read Committed;
- 旧问题解决新问题出现
图片.png
- 解决不可重复读问题
记得要将隔离级别设置为Repeatable Read
图片.png
- 坑
关于MVCC:multipart version concurrency control 多版本并发控制,在开启一个事务后进行select查询时,会默认为当前事务建立一个读取的快照(缓存),如果在另一个事务中执行了更新操作并进行了提交,且当前事务也进行了更新操作,那么快照中的缓存值将会更新
图片.png
3、幻读问题及解决
将隔离级别设置为Serializable,就会解决之前的所有情况,但是效率低下,很少使用