MySQL之事务、MVCC、乐观锁、悲观锁

并发事务

事务隔离级别:
在这里插入图片描述

并发丢失可能带来的问题:

  • 更新丢失:
    当两个或多个事务更新同一行记录,会产生更新丢失现象。可能分为回滚覆盖和提交覆盖。

    • 回滚覆盖: 即两个事务A和B操作同一条记录,A更新数据后,B紧接着回滚了数据。
    • 提交覆盖: 即两个事务A和B操作同一条记录,A提交事务后,B再次提交,将A的数据进行的覆盖。
  • 脏读:
    一个事务读取到了另一个事务修改但未提交的事务。

  • 不可重复读:
    一个事务中多次读取同一行记录,读取结果不一致。

  • 幻读:
    一个事务中多次按照相同条件查询,多次查询结果不一致,多了或少了几行记录。

  • 读未提交:

    • Read Uncommitted 读未提交:解决了回滚覆盖类型的更新丢失,但可能发生脏读现象。
  • 读已提交:

    • Read Committed 读已提交:解决了脏读,只能读取到其他会话中已经提交的数据。
  • 可重复度:默认隔离级别

    • Repeatable Read 可重复度:解决了不可重复读,确保同一事务的多个实例在并发读取数据时,会看到同样的数据。可能出现幻读。
  • 串行化:

    • Serializable 串行化:所有的增删改查串行执行。解决幻读等问题,但是可能出现大量请求超时和锁竞争,效率低。

数据库隔离级别越高,并发问题越小,同时并发处理能力越差


解决方法
  • 排队
    最简单的方法,不需要加锁,数据库某一时刻仅处理一个事务操作,特点是强一致性,处理性能低。类似ATM机存取款。在这里插入图片描述
    在这里插入图片描述

  • 排他锁
    又称独占锁,互斥锁,如果事务之间涉及到相同的数据项时,先进入事务独占数据项后,其他事务被阻塞,等待前面事务释放锁。类似视频通话,A先进行通话,B只能等待。
    在这里插入图片描述

  • 读写锁
    读和写操作:读读,写写,读写,写读
    读写锁就是进一步细化锁的颗粒度,区分读、写操作,让读和读之间不加锁。
    在这里插入图片描述

  • MVCC
    多版本控制MVCC,主要思想就是 Copy on Write,MVCC支持读和写,写和读并行操作,但为了保持一致性,写和写无法并行。

    概念:

    • 多版本控制,在每次事务修改前,都会在Undo Log 中记录修改前的数据状态和事务号,供其他事务进行读操作,还可以在必要的时候进行数据回滚。
      在这里插入图片描述

实现原理:

  • 最大的好处是读不加锁,读写不冲突。适合在读多写少的系统中,大大提高了系统的并发性能,不过目前MVCC只能在 Read Commited(读已提交) 和 Repeatable Read(可重复度) 两种隔离级别下工作。

    • 快照读:读的是快照版本(有可能是历史版本),无需加锁。(select属于快照读)
      • 快照读在 Read CommitedRepeatable Read 中的区别:Read Commited 每次读时都会创建全新的read_view,而Repeatable Read只有在第一次读时会创建read_view,再次读时,会直接拿第一次创建的read_view进行返回
      • 当前读:读的是当前记录最新的版本,并且在返回时会进行加锁,避免在这个过程中其他事务对该记录进行修改。(insert/update/delete属于当前读,内部机制会在操作前会先读取数据库中的最新数据)

    在这里插入图片描述

  • DB_ROW_ID 隐含ID:创建聚簇索引时自动创建出的id号

  • DB_TRX_ID 事务ID:每执行一次事务,事务id号自增1

  • DB_ROOT_PT 回滚指针:指向当条记录的 undo log 日志回滚号

在这里插入图片描述

  • 执行流程:
    • 1.加排他锁
    • 2.记录到Redo Log中
    • 3.复制到Undo Log中
    • 4.修改数据并提交
      MVCC机制实现了读读、读写、写读的并发处理能力
    • 写写操作:
      • 乐观锁:每个事务一起改,先提交的事务为主,后提交的报错,效率高
      • 悲观锁:该事务查询出来该记录时就加上锁,在写的操作时其他事务无法对该条记录进行操作,避免了写写操作,效率低

事务隔离级别和锁的关系

  1. 事务隔离级别是SQL92定制的标准,是对事务并发控制的整体解决方案,本质上是对锁和MVCC使用的封装,隐藏了底层细节。
  2. 锁是数据库实现并发控制的基础,事务隔离性是采用锁来实现,对响应操作加不同的锁,就可以防止其他事务同时对数据进行读写操作。
  3. 对用户来讲,首先选择使用隔离级别来控制事务,当选用的隔离级别不能解决并发问题或需求时,才有必要在开发中手动的设置锁。

MySQL隔离级别控制
查看当前隔离级别命令:show variables like ‘tx_isolation’;select @@tx_isolation;
设置全局隔离级别命令:set global tx_isolation = ‘READ-UNCOMMITTED’;

  • 四种隔离级别

    READ-UNCOMMITTED  读未提交
    READ-COMMITTED    读已提交
    REPEATABLE-READ   可重复度 -> 默认隔离级别
    SERIALIZABLE      串行化
    

其他章节 -> 跳转

end...
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

s_wei_

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

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值