事务的并发问题-mysql为例

本文详细探讨了在MySQL中事务的并发问题,包括脏读、不可重复读和幻读三种情况,并通过不同隔离级别的设置展示了它们的具体表现。通过示例展示了各隔离级别下事务的读写行为,强调了隔离级别对并发性能和数据一致性的权衡。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 事务的并发问题(3个问题)

1)脏读:事务A读取了事务B更新的数据,然后事务B回滚,那么事务A读取到的数据就是脏数据

2)不可重复读:事务A多次读取同一数据,事务B在事务A多次读取的过程中对数据做了更新并提交,导致事务A多次读取同一数据的结果不一致,侧重于修改

3)幻读: 系统管理员A将数据库中所有的学生的成绩从具体分数改为ABCD等级,同时系统管理员B插入了或删除了一条具体分数的记录,导致A发现结束后还有一条数据没有改过来或是丢失了,就好像出现了幻觉一样


SessionA:

1)设置隔离级别read-uncommited

2)开启事务 start transaction

3) 查询

SessionB:

1) 设置隔离级别read-uncommited

2) 开启事务 start transaction

3) update

Session A:

4)再次查询

发现SessionA 读取到了 SessionB中的更改,出现了脏读


SessionA:

1)设置隔离级别read commited

2)开启事务 start transaction

3) 查询

 select * from account;
 select @@tx_isolation;
 set session transaction ISOLATION level read COMMITTED;
SELECT * from account;

3) 查询

SessionB:

1) 设置隔离级别read-commited

2) 开启事务 start transaction

3) update
4) commit

 set session TRANSACTION ISOLATION level read COMMITTED;
 start TRANSACTION;
 update account set balance = balance -50 where id =1
SELECT * from account;

SessionA:

5) 查询,
不能读取SessionB 未能commit 的改动,但是能读取到sessionB中已经commit的改动


SessionA:

1)设置隔离级别repeatable read

2)开启事务 start transaction

3) 查询

SessionB:

1)设置隔离级别repeatable read

2)开启事务 start transaction

3) insert or update

4) commit

SessionA:

4) 再次查询,又再次查询……多次查询, 发现不能读取 sessionB已经提交的改动,实现了可重复读

5) commit;

6) 再次查询(注意是commit后查询),发现可以读取sessionB已经提交的改动, 但是4)和该步骤 的查询结果不一样, 出现了幻读


SessionA:

1)设置隔离级别serializable

2)开启事务 start transaction

3) 查询

SessionB:

1)设置隔离级别serializable

2)开启事务 start transaction

3) 查询,可以查询到,但比较慢

4)insert or update ,经过漫长等待后,发现insert or update 均没有成功

SessionA:

4)commit;

SessionB:

5)insert or update

6) 查询 ,发现insert or update 成功了!!!

参考:

https://www.cnblogs.com/huanongying/p/7021555.html

参考文章的结论:

补充:

  1、SQL规范所规定的标准,不同的数据库具体的实现可能会有些差异

  2、mysql中默认事务隔离级别是可重复读时并不会锁住读取到的行

  3、事务隔离级别为读提交时,写数据只会锁住相应的行

  4、事务隔离级别为可重复读时,如果有索引(包括主键索引)的时候,以索引列为条件更新数据,会存在间隙锁间隙锁、行锁、下一键锁的问题,从而锁住一些行;如果没有索引,更新数据时会锁住整张表。

  5、事务隔离级别为串行化时,读写数据都会锁住整张表

   6、隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大,鱼和熊掌不可兼得啊。对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为Read Committed,它能够避免脏读取,而且具有较好的并发性能。尽管它会导致不可重复读、幻读这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值