乐观锁和悲观锁

目录

  • 乐观锁和悲观锁是什么/可以被用在什么样的场景下?
  • 乐观锁和悲观锁的区别?

  • 乐观锁的原理:
    乐观锁的实现引入的版本号的机制,版本号version id 记录的是当前数据被修改的次数。加入当前的money = 100,version = 1,一个事务试图给money字段扣款30元。需要三步:
    1. 查询出money = 100, version = 1
    2. left = money - 30 = 70,cur-version = version + 1 = 2
    3. 写入 money = left ,verson = cur-version

乐观锁的机制需要保证:写入的时候,需要确保cur-version一定大于version。这样会保证在这段时间没有其他事务对这个字段进行修改。举个例子,事务1是消费30元的亲求,事务2是添加50元的请求,如果同时操作的话,乐观锁的机制是如果避免数据的一致性被破坏的。

事务1 事务2
查询出money = 100, version = 1
left = money - 30 = 70,cur-version = version + 1 = 2
查询menoy = 100,version=1
left = money + 50 = 150,cur-version = version + 1 = 2
写入 menoy = 150, version = 2
写入 (这个时候db中的version已经是2了。所以,不允许事务1再次写入了)

当事务1在写入的时候,事务2已经对数据进行了修改,这个时候version号变大,事务1再写入的时候,发现version号已经等于自己的版本号了,说明有其他的事务已经修改过了,那么事务1的操作需要retry。

这个特性被很多数据库支持,tcaplusdb的开发文档也提到了自己的这个买点。


  • 同样的问题,对比悲观锁要怎么解决?

    begin;
    
    // for update 对索引加锁
    // 当然可以通过应用层的逻辑进行加锁
    select xxxx from table where id = xxx  for update;
    
    update table set xxx = 'xx' where id = xxx;
    commit;
    

    对比乐观锁

    select xxx, version from table where id = xxx;
    
    update table set name = 'xx' , version = verion + 1 where id = x and version = ‘查询到的版本号’;
    

这里想表达的是乐观锁是一种解决一致性问题的工具,上述举了一个数据库层面的一个例子。但实际中也不一定要限制在数据库层面,在业务层也可以用实现一个“乐观锁”在解决问题。


  • 参考:
  1. http://www.hollischuang.com/archives/909

  2. https://zhuanlan.zhihu.com/p/40211594

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容