SpringBoot 悲观锁 与 乐观锁
乐观所和悲观锁策略
- 悲观锁:在读取数据时锁住那几行,其他对这几行的更新需要等到悲观锁结束时才能继续 。
- 乐观所:读取数据时不锁,更新时检查是否数据已经被更新过,如果是则取消当前更新,一般在悲观锁的等待时间过长而不能接受时我们才会选择乐观锁。
在SELECT 的读取锁定主要分为两种方式:
-
SELECT ... LOCK IN SHARE MODE
-
SELECT ... FOR UPDATE
这两种方式在事务(Transaction) 进行当中SELECT 到同一个数据表时,都必须等待其它事务数据被提交(Commit)后才会执行。
而主要的不同在于LOCK IN SHARE MODE 在有一方事务要Update 同一个表单时很容易造成死锁。
简单的说,如果SELECT 后面若要UPDATE 同一个表单,最好使用SELECT ... UPDATE。
需要注意的是:由于InnoDB 预设是Row-Level Lock,所以只有「明确」的指定主键,MySQL 才会执行Row lock (只锁住被选取的数据) ,否则MySQL 将会执行Table Lock (将整个数据表单给锁住)。
乐观锁机制:
- 乐观锁是一种不使用数据库锁的机制,并且不会造成线程的阻塞,只是采用多版本号机制来实现。但是,因为版本号的冲突造成了请求失败的概率剧增,所以这时往往需要通过重入的机制将请求失败的概率降低,多次的重入会带来过多执行SQL语句的问题;为了克服这个问题,可以考虑使用按时间戳或者限制重入次数的办法。