事务的并发问题与隔离级别
事务的并发问题
- 在并发场景下,就可能出现三种事务的并发问题
- 脏读(Dirty read)
- 不可重复读(Unrepeatableread)
- 幻读(Phantom read)
并发问题解释:
- 脏读:当一个事务正在访问数据并且对数据进行了修改,而这种修改还没有提交到数据库中,这时另外一个事务也访问了这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另外一个事务读到的这个数据是“脏数据”,依据“脏数据”所做的操作可能是不正确的。
时间点 |
事务A |
事务B |
1 |
开启事务A |
|
2 |
|
开启事务B |
3 |
查询余额为100 |
|
4 |
|
修改余额为150 |
5 |
查询余额为150 |
|
6 |
|
事务回滚 |
- 不可重复读:在第一个事务中的两次读数据之间,由于第二个事务的修改导致第一个事务两次读取的数据可能不太一样。这就发生了在一个事务内两次读到的数据是不一样的情况,因此称为不可重复读
时间点 |
事务A |
事务B |
1 |
开启事务A |
|
2 |
|
开启事务B |
3 |
查询余额为100 |
|
4 |
|
修改余额为150 |
5 |
查询余额为100 |
|
6 |
|
提交事务 |
7 |
查询余额为150 |
|
- 幻读:幻读与不可重复读类似。它发生在一个事务(T1)读取了几行数据,接着另一个并发事务(T2)插入了一些数据时。在随后的查询中,第一个事务(T1)就会发现多了一些原本不存在的记录,就好像发生了幻觉一样
时间点 |
事务A |
事务B |
1 |
开启事务A |
|
2 |
|
开启事务B |
3 |
查询id<3的所有记录,共3条 |
|
4 |
|
插入一条记录id=2 |
5 |
|
提交事务 |
6 |
查询id<3的所有记录,共4条 |
|
- 不可重复读与幻读的区别:不可重复读的重点是修改,幻读的重点是新增或删除
- 解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表
事务并发问题解决方案
- 事务的隔离级别用于决定如何控制并发用户读写数据的操作。数据库是允许多用户并发访问的,如果多个用户同时开启事务并对同一数据进行读写操作的话,有可能会出现脏读、不可重复读和幻读问题,所以MySQL中提供了四种隔离级别来解决上述问题。
- 事务隔离级别从高到低共有READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ以及SERIALIZABLE四种
- 隔离级别越低,高并发执行效率越高
隔离级别 |
脏读 |
不可重复读 |
幻读 |
READ UNCOMMITTED |
√ |
√ |
√ |
READ COMMITTED |
× |
√ |
√ |
REPEATABLE READ |
× |
× |
√ |
SERIALIZABLE |
× |
× |
× |
√代表会出现问题,×代表不会出现问题
-- 查看默认的事务隔离级别 MySQL默认的是repeatable read
select @@transaction_isolation;
-- 设置事务的隔离级别 (设置当前会话的隔离级别)
set session transaction isolation level read uncommitted;
set session transaction isolation level read committed;
set session transaction isolation level repeatable read;
set session transaction isolation level serializable;