栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

MySQL的乐观锁,悲观锁与MVCC原理讲解

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

MySQL的乐观锁,悲观锁与MVCC原理讲解

Mysql的并发场景

数据库并发场景有三种

读读 :读取之间应该不存在竞争问题,所以不需要枷锁
读写:有线程安全问题,可能会造成事务隔离性问题,可能遇到脏读,幻读,不可重复读
写写:有线程安全问题,可能会存在更新丢失问题,比如第一类更新丢失,第二类更新丢失
悲观锁

维基百科:在关系数据库管理系统里,悲观并发控制(又名“悲观锁”,PessimisticConcurrencyControl,缩写“PCC”)是一种并发控制的方法。它可以阻止一个事务以影响其他用户的方式来修改数据。如果一个事务执行的操作读某行数据应用了锁,那只有当这个事务把锁释放,其他事务才能够执行与该锁冲突的操作。

实现方式:
1)事务获取锁,成功后,其他事务不能对数据进行操作
2)失败后等待其他事务释放锁

  • 优点:
    悲观并发控制采取的是保守策略:“先取锁,成功了才访问数据”,这保证了数据获取和修改都是有序进行的,因此适合在写多读少的环境中使用。
  • 缺点:
    由于需要加锁,而且可能面临锁冲突甚至死锁的问题,悲观并发控制增加了系统的额外开销,降低了系统的效率,同时也会降低了系统的并行性。
  • 总结:悲观并发控制可以解决读-写冲突和写-写冲突,指在用加锁的方式去解决
乐观锁

维基百科:在关系数据库管理系统里,乐观并发控制(又名“乐观锁”,OptimisticConcurrencyControl,缩写“OCC”)是一种并发控制的方法。它假设多用户并发的事务在处理时不会彼此互相影响,各事务能够在不产生锁的情况下处理各自影响的那部分数据。

实现方式:
CAS(比较与交换,Compare and swap)是一种有名的无锁算法。无锁编程,即不使用锁的情况下实现多线程之间的变量同步,也就是在没有线程被阻塞的情况下实现变量的同步,所以也叫非阻塞同步

  • 优点:
    乐观并发控制没有实际加锁,所以没有额外开销,也不错出现死锁问题,适用于读多写少的并发场景,因为没有额外开销,所以能极大提高数据库的性能。
  • 缺点:
    乐观并发控制不适合于写多读少的并发场景下,因为会出现很多的写冲突,导致数据写入要多次等待重试,在这种情况下,其开销实际上是比悲观锁更高的。而且乐观锁的业务逻辑比悲观锁要更为复杂,业务逻辑上要考虑到失败,等待重试的情况,而且也无法避免其他第三方系统对数据库的直接修改的情况。
  • 总结:乐观并发控制可以解决读-写冲突和写-写冲突,指在用不进行枷锁的方式去解决
MVCC 多版本并发控制

维基百科: 多版本并发控制(Multiversion concurrency control, MCC 或
MVCC),是数据库管理系统常用的一种并发控制,也用于程序设计语言实现事务内存。
与悲观并发控制和乐观并发控制不同的是,MVCC是为了解决读写锁造成的多个、长时间的读操作饿死写操作问题,也就是解决读写冲突的问题。

实现原理:

MVCC的目的就是多版本并发控制,在数据库中的实现,就是为了解决读写冲突,它的实现原理主要是依赖记录中的3个隐式字段,undo日志 ,ReadView 这三个点来实现的

隐式字段:
DB_TRX_ID 事务id
DB_ROLL_PTR 回滚id
DB_ROW_ID数据id
注意:如果数据id 主键已经设置则式用户设置的id

undo日志
事务在进行update或delete时产生的undo log; 不仅在事务回滚时需要,在快照读(select,当读的过程中有写的十事务开始和提交,会造成读数据的脏读、不可重复读、幻读等)时也需要;所以不能随便删除,只有在快速读或事务回滚不涉及该日志时

ReadView读视图
Read View就是事务进行快照读(select * from)操作的时候生产的读视图(Read View),在该事务执行的快照读的那一刻,会生成事务系统当前的一个快照,记录并维护系统当前活跃事务

如上图所示,执行select的时候,会开启一个事务,创建一个readview,主要包含三部分,
up_limit_id ,当前活跃的最小事务id,
trx_list当前活跃的事务id集合
low_limit_id 当前最新事务id+1
此时readView为【1,3】,5
① 是否小于1 ,成立可以看到
② ①不成立(即大于1) ,需要判断事务是否小于5,不成立(即大于5)则看不见
③ ②成立(小于1) ,还需要事务id判断不在【1,3】这个集合中,在则看不到,不在则可以看到

事务级别为RR(可以重复读)
多次读数据, readView始终为同一个

事务级别为RC(不可以重复读)
多次读数据会创建多个readView

总结

总之,MVCC就是因为大牛们,不满意只让数据库采用悲观锁这样性能不佳的形式去解决读-写冲突问题,而提出的解决方案,所以在数据库中,因为有了MVCC,所以我们可以形成两个组合:
MVCC + 悲观锁 MVCC解决读写冲突,悲观锁解决写写冲突 (竞争激烈) MVCC + 乐观锁 MVCC解决读写冲突,乐观锁解决写写冲突 (竞争不激烈)

参考文档
https://blog.csdn.net/SnailMann/article/details/88388829
https://www.cnblogs.com/xuwc/p/13873611.html

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/309791.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号