6
回答
关于乐观锁的疑问,求解
终于搞明白,存储TCO原来是这样算的>>>   

乐观锁( Optimistic Locking ) 相对悲观锁而言,乐观锁机制采取了更加宽松的加锁机制。悲观锁大多数情况下依靠数据库的锁机制实现,以保证操作最大程度的独占性。但随之而来的就是数据库性能的大量开销,特别是对长事务而言,这样的开销往往无法承受。而乐观锁机制在一定程度上解决了这个问题。乐观锁,大多是基于数据版本( Version )记录机制实现。何谓数据版本?即为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是通过为数据库表增加一个 “version” 字段来实现。读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时,将提交数据的版本数据与数据库表对应记录的当前版本信息进行比对,如果提交的数据版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据。

在更新之前,会读出版本号进行一个匹配,若更新的数据版本号大于数据库表当前版本号,则可以更新,但是我有一个疑问,在高并发情况下,比如两次更新同时到达,比较版本号的时候都是大于当前数据库表当前版本号,那岂不version的校验根本没有用了,都可以更新成功了?那这样的话,乐观锁不就是不支持并发情况了。求解,谢谢!




<无标签>
举报
共有6个答案 最后回答: 2年前

引用来自“王大叔爱编程”的评论

这个问题,可以参考下面这个帖子

http://www.itpub.net/thread-1928001-1-1.html

1,从业务场景看,根据业务场景选用悲观锁和乐观锁,在查询后修改前,如果数据被改的概率大,则应选用悲观所,换句话就是说乐观锁对并发写数据这种情况没有很好的支持,支持读多写少的场景。

2、从持有锁的时间上面看,这两种策略的核心其实就是持有锁的时间的起止点不同,悲观锁是从读取记录的那一刻就开始了,而乐观锁只从UPDATE那一刻开始;结束的点两者是一样的,都是发出commit或rollback命令。所以,悲观锁策略会使锁的持续时间更长,而乐观锁的持续时间则较短。其影响就是并发。悲观锁的并发性低于乐观锁。

你这样的理解还没有完全理解乐观锁,其实不是你画是这个图,简单和你说明一下:

正如你所说的,假设有两个并发到来,取到一样的 version = 10,但是这两个线程都要去修改这条记录的时候,都会这样子去更新:


UPDATE table_name SET 字段1=?,字段2=?,version = 11 WHERE id = ? AND version = 10


也就是说,使用 version 乐观锁,必须在update的where条件中跟上version,这样子的话,即使多个并发到来,只要任意一个线程实行成功了一条 update 语句,数据库的 version 就已经等于 11 了,那么后面的所有并发对数据库的修改都将无法成功(因为已经不满足WHERE id = ? AND version = 10这个条件了)


明白了吧

其实大部分的业务都不需要乐观锁,

如果要用也简单,增加个字段,每次操作前先检查下这个字段的值

更新数据的时候带着这个版本号 如update X set x=X where version=1 ,如果更新的影响行数是0,则更新失败,数据已经被更新,然后根据具体情况处理。这不会存在并发问题啊,更新的时候数据库是有悲观锁的。

顶部