并发控制:(二)乐观锁 悲观锁

本文详细解释了乐观锁和悲观锁的概念及其实现方式。悲观锁基于假设冲突概率较高,采用排他锁来减少冲突;而乐观锁则基于冲突概率较低的假设,通过在提交更改时检查数据一致性来避免冲突。

  

悲观锁:(pessimistic locking)
假定:发生冲突的概率比较高,
实现:在对任意记录进行修改前,先尝试为该记录加上排他锁(exclusive locking)。这样其他事务如果想操作该记录,需要等待锁的释放
特点: 当并发量较大,频繁访问时,等待时间较长,并发访问性不好
例如: java的synchronized,SqlServer页级锁,Oracle行级锁


乐观锁:(optimistic locking)
假设:发生冲突的概率比较低
实现:在提交对记录的更改时才将对象锁住,提交前需要检查数据的完整性


比如,现有两个事务A和B,并且认为A和B是两个原子操作。
A:Cat c = findById(catId);
c.setName("NewCat");
B: update(c)
那么,在B提交前,会锁住c对象(这里代码中并没有锁操作,因为锁操作是B提交前由数据库完成的)。
同时,为了避免A执行后与B执行前之间的这段时间,c对象被其他线程改变了,所以提交前要检查数据的一致性。
检查数据的一致性的方式可以是通过时间戳,或者用自增长的整数表示数据版本号(例如Hibernate、Morphia中的@Version)
如果检查数据已经被改变了,需要回到步骤A重新运行程序,直到提交成功。或者是直接抛出异常,这要看锁的策略了。
由于假定发生冲突的概率比较低的,所以这种重试是可以容忍的,但如果是高并发,就会影响性能了。
这种控制方式也叫乐观并发控制(Optimistic concurrency control)

特点:
读取和改变该对象时不加锁,提交变更前加锁
乐观锁加锁时间要比悲观锁短
可以用较大的锁粒度获得较好的并发访问性能
会增加并发用户读取对象的次数(检查数据一致性时会多一步查询)

转载于:https://www.cnblogs.com/ppp21spider/p/5221646.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值