悲观锁和乐观锁

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/shangyanchao123/article/details/82704117

1、悲观锁

在关系数据库管理系统里,悲观并发控制(又名“悲观锁”,Pessimistic Concurrency Control,缩写“PCC”)是一种并发控制的方法。它可以阻止一个事务以影响其他用户的方式来修改数据。如果一个事务执行的操作都某行数据应用了锁,那只有当这个事务把锁释放,其他事务才能够执行与该锁冲突的操作。
悲观并发控制主要用于数据争用激烈的环境,以及发生并发冲突时使用锁保护数据的成本要低于回滚事务的成本的环境中。

1.1.在 SQL 中加入的 for update 语句,意味着将持有对数据库记录的行更新锁(因
为这里使用主键查询,所以只会对行加锁。如果使用的是非主键查询,要考虑是否对全表
加锁的问题,加锁后可能引发其他查询的阻塞〉,那就意味着在高并发的场景下 , 当一条事
务持有了这个更新锁才能往下操作,其他的线程如果要更新这条记录,都需要等待,这样
就不会出现超发现象引发的数据一致性 问题了

1.2

2、乐观锁

在关系数据库管理系统里,乐观并发控制(又名“乐观锁”,Optimistic Concurrency Control,缩写“OCC”)是一种并发控制的方法。它假设多用户并发的事务在处理时不会彼此互相影响,各事务能够在不产生锁的情况下处理各自影响的那部分数据。在提交数据更新之前,每个事务会先检查在该事务读取数据后,有没有其他事务又修改了该数据。如果其他事务有更新的话,正在提交的事务会进行回滚。乐观事务控制最早是由孔祥重(H.T.Kung)教授提出。

2.1.CAS原理

在 CAS 原理中,对于多个线程共同的资源,先保存一个旧值( Old Value ),比如进入
线程后,查询当前存量为 100 个红包,那么先把旧值保存为 100,然后经过一定的逻辑处
理。当需要扣减红包的时候,先比较数据库当前的值和旧值是否一致,如果一致则进行扣
减红包的操作,否则就认为它已经被其他线程修改过了,不再进行操作,

2.2.ABA问题
比如说一个线程one从内存位置V中取出A,这时候另一个线程two也从内存中取出A,并且two进行了一些操作变成了B,然后two又将V位置的数据变成A,这时候线程one进行CAS操作发现内存中仍然是A,然后one操作成功。

ABA问题的发生 , 是因为业务逻辑存在回退的可能性 。 如果加入一个非业务逻辑的属性
性,比如在一个数据中加入版本号( version ),对于版本号有一个约定,就是只要修改 X
变量的数据,强制版本号( version )只能递增,而不会回退,即使是其他业务数据回退,
它也会递增,那么 ABA 问题就解决了

2.3.乐观锁重入机制

因为乐观锁造成大量更新失败的问题,使用时间戳执行乐观锁重入,是一种提高成功
率的方法
    Java架构师交流群:781025218, 汇集高水平技术者,营造纯粹的技术交流平台,欢迎真正热爱技术和乐于分享朋友加入。

展开阅读全文

没有更多推荐了,返回首页