zoukankan      html  css  js  c++  java
  • 乐观锁与悲观锁

    假如有一个购买行为事务,我们更需要去跟新数据库

    update item set amount = amount - 1 where item_id = 1;

    然而当amount只有1个的时候,同时有两个顾客进入了事务进行购买行为会如何,最后amount=-1,两个顾客都获得了这个商品,这显然不合理

    而使用乐观锁和悲观锁的解决方案可以如下:

    1. 乐观锁

    1) 概念: 在执行修改操作时不判断是否存在冲突,而是到了操作完成后再判断是否存在冲突,如有冲突则回滚

    2) 适用情况: 一般适用于回滚代价低,且冲突较少的情况.

    3) 优点: 执行操作时不会造成阻塞

    4) 缺点: 如果冲突较多,将造成较多的回滚操作

    5) 实现: 一般使用版本控制的方式实现

    6) 实现例子:

    begin;

    select @cur_amount := amount from item where item_id = 1;

    update item set amount = amount - 1 where amount = @cur_amount and item_id = 1;

    commit;

    // 最后根据是否对数据更新行数是否为1来告诉用户是否购买成功

    这是使用乐观锁来更新的例子, @cur_amount是本次事务A获得的数量, 例如为 1, 而另外一个事务B假如于事务A之前执行完了跟新操作, 那么此时数据库中的amount将变为0.

    那么事务A的 update 中语句 amount = @cur_amount 将是 0 = 1 而不成立, 所以此次购买会失败

    我这里只是一个简单的例子,实际操作中,可能这个事务中间会进行大量操作,而最后会因为amount != @cur_amount 而回滚

    例如java中使用AtomicInteger的乐观锁实现(待补完)

    2. 悲观锁

    1) 概念: 在执行操作前就进行是否需要锁的判断,加入有操作正在执行,则需要等待锁释放

    2) 适用情况: 冲突较多的情况

    3) 优点: 不需要进行回滚

    4) 缺点: 需要串行执行, 会造成阻塞

    5) 实现: 使用排他锁

    6) 实现例子:

    begin;

    select amount from item where item_id = 1 for update;

    // 通过amount来做出一些行为,例如告诉用户库存不足,购买失败,然后只有amount > 1才进入更新库存操作

    update item set amount = amount - 1 where item_id = 1;

    commit;

    由于是串行执行,其他事务的for update必须等该当前事务的for update语句执行,所以我们不必担心我们获得的amount被修改过,因为它永远是最新的

    事实上,对于这种购买行为的解决方案是使用

    update item set amount = amount - 1 where item_id = 1 and amount > 0;

    由于update操作在repeatable-read中是串行执行的,所以我们大可以不加锁,直接这么一句就解决了

    当然这是一种特例,上述我只是为了解释乐观锁与悲观锁,因为实在没找到什么好的例子.

  • 相关阅读:
    [转载]Jupyter Notebook 的快捷键
    【转载】mysql行列转换方法总结
    【Deep Learning Nanodegree Foundation笔记】第 10 课:Sentiment Analysis with Andrew Trask
    赵铁夫讲单词·解密单词的潜规则【2016全新精华版】
    【转载】ERROR 1044 (42000): Access denied for user ''@'localhost' to database 'mysql'
    [IJCAI-17 口碑商家客流量预测]
    【Deep Learning Nanodegree Foundation笔记】第 9 课:Model Evaluation and Validation
    【Deep Learning Nanodegree Foundation笔记】第 5 课:Logistic Regression
    不用动笔背单词之托福
    Jenkins--02命令行构建Job
  • 原文地址:https://www.cnblogs.com/zemliu/p/3295805.html
Copyright © 2011-2022 走看看