乐观锁的简单使用 通俗易懂 超详细

乐观锁 Optimistic Locking

乐观锁的概念

乐观锁机制采取了更加宽松的加锁机制。乐观锁是相对悲观锁而言,也是为了避免数据库幻读、业务处理时间过长等原因引起数据处理错误的一种机制,但乐观锁不会刻意使用数据库本身的锁机制,而是依据数据本身来保证数据的正确性

CAS 乐观锁技术,当多个线程尝试使用CAS同时更新同一个变量时,只有其中一个线程能更新变量的值,而其它线程都失败,失败的线程并不会被挂起,而是被告知这次竞争中失败,并可以再次尝试。

为什么要用乐观锁 ?

例如银行转账流程

  • B 的账户余额为 ¥300
  • A 向 B 转账 ¥700
  • 在 A 向 B 转账的同时 C 要 取走 B 的 ¥200(此时 B 的余额还是 ¥300)
  • 这样的流程走下来后 B 的余额会覆盖成 ¥100

image

设置乐观锁后

  • C 的取款操作: 会判断数据表当前的数据与操作时的数据是否相同(数据库中B的余额 300 是否与操作时已经查出来 B 的余额是否一致)
  • 如果数据相同则会更新数据,否则会认为 已经查出来 B 的数据为过期数据

image

使用乐观锁后却产生了新的问题,就是ABA问题

  • ABA问题: A 将 B 更新成 ¥1000 后 D 又将 B 更新为 ¥300,此时的 C 还认为 B 没有被更新过,C 的操作还是会成功.但不代表这个过程就是没有问题的

image

为了解决ABA问题,在数据库表中增加version字段

  • 其目的是达到顺序递增,也就是修改这条数据后version会产生变化,这样其他正在操作这条数据的线程都会执行失败,因为他们都变成了过期数据
  • 例子:update t_user set sex = 1,version = version + 1 where user_id = 1 and version = 0;
    这句SQL语句执行第一次会执行成功,执行第二次就会失败,因为version已经发生改变

image

发展趋势

在当前高并发,高可用等并发量较大情况下使用乐观锁基本成为第一选择

乐观锁并未真正的加锁,效率高。一旦锁的力度掌握不好,更新失败的概率就会比较高,也很容易发生业务失败

本文就先说到这里,有问题欢迎留言讨论

posted @ 2020-07-31 12:07  SourceLife_Bx  阅读(1131)  评论(0编辑  收藏  举报