【锁】乐观锁和悲观锁的实现机制

乐观锁

1、版本号机制

数据库的MVCC机制就是这种,MVCC更加严格一点,后边增加了创建版本及删除版本两个字段。

详情参考:
https://blog.csdn.net/numbbe/article/details/109300087

版本号机制也是CAS操作的一种,先比较再替换。

比如我有一个学生表,有两个字段,饭卡余额和版本,初始化为,饭卡余额为100,版本为1。

1、线程A吃饭刷了20块钱,修改余额为80,首先进行读操作,记录学生此时余额为100,版本号为1。

2、线程B吃饭刷了40块钱,修改余额为60,首先进行读操作,记录学生此时余额为100,版本号为1。

3、线程A要提交了,提交的版本为1+1=2,再次读,看一下最新的数据,提交版本>当前版本1,可以提交,提交成功。

4、线程B要提交了,提交的版本为1+1=2,再次读,看一下最新的数据,提交版本为2,当前版本为2,不满足【提交版本>当前版本】前提条件,提交失败。

(这里直接比对版本号,也可以,如果版本号和自己记录的版本号不一致,说明有人动过了,就不提交)

(这两种比较方式,都是判断一下有没有其他线程对数据进行了更改)

(百度了很多文章,有说比对版本号是否相等的,有说判断版本大小的,到底怎么回事,咱也不知道)

线程A与线程B是有先后顺序的,线程A更新执行后,线程B再执行, 这个时候线程B应该使用最新的数据,而不是使用版本1的旧数据。

你要提交的数据,版本号是要大于当前版本的。如果小于等于当前最新版本,说明已经有其他线程修改过了。

2、CAS操作

简而言之,读读写。

第一次读,记录数据。

第二次读,比对数据。

开始写。

compare and swap,无锁算法,非阻塞式同步。

CAS算法涉及三个操作数。

  • 旧值 V
  • 比较值 A
  • 新值 B

当且仅当A与V相等时,CAS通过原子方式用新值B更新V。

悲观锁

我们最经常使用的锁,比如下边这两个都是悲观锁,悲观锁加锁,乐观锁不加锁。

1、synchronized

参考:

https://blog.csdn.net/numbbe/article/details/113178567

2、lock

参考:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
乐观锁悲观锁是并发控制中常用的两种策略。 乐观锁实现方式是,当多个事务同时访问同一数据时,假设每个事务都能成功地完成操作,直到提交时才会检查是否有冲突。如果检测到冲突(比如数据已被其他事务修改),则会回滚当前事务并重新尝试。 乐观锁实现通常通过为每一条记录添加版本号或时间戳来实现。当事务读取数据时,会记录下当前版本号或时间戳。在提交时,会检查数据库中的当前版本号或时间戳与事务开始时记录的版本号或时间戳是否一致,如果不一致则说明数据已被其他事务修改过,需要回滚当前事务并重新尝试。 悲观锁实现方式是,在事务执行期间,对数据进行加以阻止其他事务对其进行修改。悲观锁认为在事务执行期间会发生冲突,因此提前对数据进行加以避免冲突。 悲观锁实现通常通过数据库的机制实现,比如对某条记录加上排它(Exclusive Lock)或共享(Shared Lock)。排它会阻止其他事务对该记录进行读取和修改,而共享只会阻止其他事务对该记录进行修改,但允许读取。 需要注意的是,乐观锁悲观锁各有优缺点,适用于不同的并发场景。乐观锁适用于读多写少的场景,并发性能较好;而悲观锁适用于写多读少的场景,保证数据的一致性和安全性。在实际应用中,根据具体情况选择合适的并发控制策略是很重要的。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值