美文网首页
MySQL悲观锁和乐观锁

MySQL悲观锁和乐观锁

作者: 皮蛋馅儿 | 来源:发表于2020-04-09 12:47 被阅读0次

悲观锁

悲观锁的特点是先获取锁,再进行业务操作,即“悲观”地认为获取锁是非常有可能失败的,因此要先确保获取锁成功再进行业务操作。

通常所说的“一锁二查三更新”即指的是使用悲观锁。通常来讲在数据库上的悲观锁需要数据库本身提供支持,即通过常用的select … for update操作来实现悲观锁。当数据库执行select for update时会获取被select中的数据行的行锁,因此其他并发执行的select for update如果试图选中同一行则会发生阻塞(需要等待行锁被释放),因此达到锁的效果。select for update获取的行锁会在当前事务结束时自动释放,因此必须在事务中使用。

另外mysql还有个问题是select for update语句执行中所有扫描过的行都会被锁上,这一点很容易造成问题。因此如果在mysql中用悲观锁务必要确定走了索引,而不是全表扫描。

乐观锁

乐观锁的特点先进行业务操作,不到万不得已不去拿锁。即“乐观”地认为拿锁多半是会成功的,因此在进行完业务操作需要实际更新数据的最后一步再去拿一下锁就好。

乐观锁在数据库上的实现完全是逻辑的,不需要数据库提供特殊的支持。一般的做法是在需要锁的数据上增加一个版本号,或者时间戳,然后按照如下方式实现:

1. SELECT data AS old_data, version AS old_version FROM …;
2. 根据获取的数据进行业务操作,得到new_data和new_version
3. UPDATE SET data = new_data, version = new_version WHERE version = old_version
if (updated row > 0) {
    // 乐观锁获取成功,操作完成
} else {
    // 乐观锁获取失败,回滚并重试
}

乐观锁是否在事务中其实都是无所谓的,其底层机制是这样:在数据库内部update同一行的时候是不允许并发的,即数据库每次执行一条update语句时会获取被update行的写锁,直到这一行被成功更新后才释放。因此在业务操作进行前获取需要锁的数据的当前版本号,然后实际更新数据时再次对比版本号确认与之前获取的相同,并更新版本号,即可确认这之间没有发生并发的修改。如果更新失败即可认为老版本的数据已经被并发修改掉而不存在了,此时认为获取锁失败,需要回滚整个业务操作并可根据需要重试整个过程。

相关文章

  • 乐观锁和悲观锁

    参考来源 深入理解乐观锁与悲观锁 乐观锁的一种实现方式——CAS mysql乐观锁总结和实践 乐观锁和悲观锁 悲观...

  • rails中乐观锁和悲观锁的使用

    MySQL乐观锁和悲观锁的介绍可以参考之前的一篇文章MySQL中的锁(行锁,表锁,乐观锁,悲观锁,共享锁,排他锁)...

  • 蚂蚁面试

    1、mysql乐观锁和悲观锁的区别? 乐观锁通过MVCC,版本实现,悲观锁select... for update...

  • 表锁和行锁

    MySQL中的锁总体可以分为悲观锁和乐观锁。悲观锁MySQL中有自带的锁。乐观锁需要自己写程序控制来实现乐观锁的功...

  • mysql的悲观和乐观锁

    谈谈mysql的悲观和乐观锁 - 周伯通的麦田 - 博客园 悲观锁 select … for update 乐观锁...

  • mysql锁

    mysql锁 性能:乐观锁,悲观锁 操作类型:读锁,写锁,都属于悲观锁 操作粒度:行锁,表锁 乐观锁:一种思想,通...

  • mysql锁记录

    mysql锁 性能:乐观锁,悲观锁 操作类型:读锁,写锁,都属于悲观锁 操作粒度:行锁,表锁 乐观锁:一种思想,通...

  • 秒杀随笔

    方法: mysql悲观锁 mysql乐观锁 PHP+redis分布式锁 PHP+redis乐观锁(redis wa...

  • 看完你就知道的乐观锁和悲观锁

    看完你就知道的乐观锁和悲观锁 Java 锁之乐观锁和悲观锁 [TOC] Java 按照锁的实现分为乐观锁和悲观锁,...

  • mysql中的乐观锁和悲观锁

    关于mysql中的乐观锁和悲观锁面试的时候被问到的概率还是比较大的。 mysql的悲观锁: 其实理解起来...

网友评论

      本文标题:MySQL悲观锁和乐观锁

      本文链接:https://www.haomeiwen.com/subject/ctgqmhtx.html