在实际项目中,对数据的更新操作是避免不了的。保持数据的一致性是非常重要的。 

  之前考虑到是否可以通过比较update的时间,或者单独保存一个时间戳字段来进行比较,但需要手动更新,比较麻烦且容易出错。
  与朋友的沟通中发现了更便捷的方式。如果项目中使用了myBatisPlus,则较为便捷的解决了这一问题。 只要是通过对数据添加乐观锁来实现。 
    

什么是乐观锁?

乐观锁(Optimistic Locking)是相对悲观锁而言的,乐观锁假设数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突进行检测。如果发现冲突了,则返回给用户错误的信息,让用户决定如何去做。乐观锁适用于读操作多的场景,这样可以提高程序的吞吐量。

乐观锁实例:

(1)存在两个线程 A 和 B,分别从数据库读取数据。执行后,线程 A 和 线程 B 的 version 均等于 1。如下图:

                    

(2)线程 A 处理完业务,提交数据。此时,数据库中该记录的 version 为 2。如下图:

 

(3)线程 B 也处理完业务了,提交数据。此时,数据库中的 version 已经等于 2,而线程的 version 还是 1。程序给出错误信息,不允许线程 B 操作数据。如下图:

   

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

  • CAS 实现:Java 中 java.util.concurrent.atomic 包下面的原子变量使用了乐观锁的一种 CAS 实现方式。

  • 版本号控制:一般是在数据表中加上一个数据版本号 version 字段,表示数据被修改的次数。当数据被修改时,version 值会+1。当线程A要更新数据值时,在读取数据的同时也会读取 version 值,在提交更新时,若刚才读取到的 version 值与当前数据库中的 version 值相等时才更新,否则重试更新操作,直到更新成功。


  文章:https://www.hxstrive.com/subject/mybatis_plus.htm?id=307