MySQL 事务并发问题(详解)



1-并发事务导致的问题

假设现在有A,B两个事务,这两个事务都可以对数据库进行读取和修改。那么,排列组合后可以分为三种情况(都是以操作同一资源为前提):

情况操作结果
1A,B都采取读操作不会出现任何问题
2其中一个事务进行修改,另一个则进行读取执行修改的那个事务不会出错,执行读操作的事务读取的数据会出现问题(称为读问题,下面会详细介绍)
3A,B都对数据库进行修改在对同一数据进行修改时,先修改的数据会被后修改的数据覆盖(称为更新问题,下面会详细介绍)



1.1读问题

读问题分为三类(我们假定执行读操作的事务为A,执行修改的事务为B):

问题名称解释
脏读即A在B还未提交数据时读取数据。因为你不知道B事物之后执行的是回滚还是提交,所以你不能保证此数据的可靠性。
不可重复读A在B提交数据前读取一次,然后在B提交数据后再读取一次。造成A事务内部多次读取的结果不一样。
幻读A 在B插入数据前读取一次,然后在B插入数据后再读取一次。造成A事务内部前后两次查询结果不一致

1.2更新问题

以修改数据库中表的数据为例。A修改好表中的某一数据准备提交时,B立即修改此表中的其它项数据。A正常提交数据,然后B也正常提交数据。

时间点事务A事务B
1开启事务
2开启事务
3update t_sutdent ts set ts.sname=“张三” where ts.sid=“10”
4update t_sutdent t set t.sname=“李四”,t.age=18 where ts.sid=“10”
5提交
6提交
问题事务A认为数据库中的数据已成功改为:sid=10的学生的姓名为“张三”。(实际上是“李四”)事务B认为数据库已修改成功。(确实修改成功,但却覆盖了A的数据,且A并不知晓

解决方法:
  • 使用排它锁(首句添加“for update”): 把写写并行改为写写串行(如下表)。简单地说就是A,B在执行数据修改时要排队。而且当某一进程正在修改时,其它进程不能查询。

    时间点事务A事务B
    1开启事务
    2修改数据不可开启事务
    3提交数据不可开启事务
    4开启事务
    5不可开启事务修改数据
    6不可开启事务提交数据
  • 使用乐观锁(添加version或时间戳): 在写写并行发生冲突时报异常1,交给程序员处理。




2-事务的隔离级别

事务的四种隔离级别:

种类处理的问题解释
串行化三个读问题都能处理顾名思义,此方法下,对同一数据的访问是串行的。没有并发,就不会出现任何并发问题。此级别基本不使用,一是效率底;二是容易出现死锁。
可重复读不能处理幻读mysql有两种机制能达到此级别的隔离效果。一、加读锁(读读共享) + 加写锁(读写串行):实现简单,但因为读写无法并行,所以效率低;二、读不加锁 + 加写锁 + MVCC(有兴趣的可以自行百度):实现复杂,但读写可以并行2,效率高。
读已提交数据只能处理脏读操作:写时加排它锁,读时不加操作。 引用大佬的话(原文找不到了):在mysql的MVCC机制和该隔离级别的共同作用下,每次select的时候数据库会新生成一个版本号,所以每次select的时候读的不是一个副本 而是不同的副本。每次select之间有其他事务更新了,而我们读取数据并提交了,那就出现了不可重复读。所以虽然此级别效率高,但是mysql不能使用。
读未提交数据即,不做任何处理。





  1. 假如我们规定,数据库原始的version为0,在某个事务对其进行修改后要把version + 1后才能存入数据库。那么,只要 存入的version < 当前数据库的version,就把它判定为丢失更新。通常遇到这种问题时,更新数据库版本就行(需要程序员自己实现)。 ↩︎

  2. 当原数据被写锁占用时,读请求可以去读取数据库的副本,又因为并行的写操作加了写锁(写的这段时间数据库不能给出副本)所以得到的副本只有两种情况:一、改写之前的副本;二、改写后的副本。这样便解决了更新问题。 ↩︎

  • 1
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云刘刘

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值