美文网首页
03丨事务隔离:为什么你改了我还看不见?

03丨事务隔离:为什么你改了我还看不见?

作者: 意大利大炮 | 来源:发表于2023-05-25 20:06 被阅读0次

    事务隔离级别(基于InnoDB引擎)

    写锁

    • 在进行增删改时,MySQL 会默认加上写锁 (排它锁)
    • 在进行查询时,不会默认加锁。
    • 读锁只排斥写锁,写锁排斥读锁和写锁

    结论一:事务1执行更新语句(更新id=1的数据),其他任何事务执行更新语句(更新id=1的数据)都会等待。
    结论二:事务1执行查询语句,不影响其他任何事务的更新、查询
    结论三:事务1增加读锁(lock in share mode;对id=1的数据),其他任何事务都不能执行更新语句(对id=1的数据)

    问题1: 有了结论一,是不是更改余额类的操作就不需要并发控制了?

    • 结论:不是的。此结论只保证了原子类更新语句的并发;
    • 比如:test表:id=1,value=1;
      事务1:update test value SET value = value + 1 WHERE id = 1;
      事务2:update test value SET value = value + 2 WHERE id = 1;
      事务1:commit
      事务2:commit
      此时value = 4(正确)
      原因:比如两个事务都要更改记录(id=1)的记录的value字段;
    • 反例:
      比如:test表:id=1,value=100;
      事务1:
      select value FROM test WHERE id = 1
      if value >= 100;
      // 扣减30
      update test value SET value = 70 WHERE id = 1;
      事务2:
      select value FROM test WHERE id = 1
      if value >= 100;
      // 扣减80
      update test value SET value = 20 WHERE id = 1;
      事务1commit;
      事务2commit;
      此时value = 20;但他应该被扣减了两次[30、80],值应该为-10
    • 解决:
    1. 查询时就增加写锁
      select value FROM test WHERE id = 1 for update
    2. 使用乐观锁(cas)
      update test value SET value = 20 WHERE id = 1 and value = 100

    问题二:读锁有什么用?
    待解答

    可重复读

    每一个语句在事务里在第一次读时,建立镜像,后续再读此语句都不会改变。

    相关文章

      网友评论

          本文标题:03丨事务隔离:为什么你改了我还看不见?

          本文链接:https://www.haomeiwen.com/subject/jkwhedtx.html