データベースの同時実行による更新の損失の4つの解決方法

3174 ワード

1.問題の説明

  • 独立性レベル:Read Commited
  •  A                                     B
    select amount=1000
                                              select amount =1000
                                               100 
                                              update amount =900
                                              commit
     100 
    update amount= 1100
    commit
    
  • は正確には1000のはずだったが、結果は1100
  • になった.

    2.解決方法


    2.1方法一:Repeatable Read


    独立性レベルがRepeatable Readに変更されると、すべてのselectがロックされます.

    2.2方法2:悲観ロック

  • 取引A
  • select AMOUNT as amount from MONEY_TABLE for update;
    amount -= 100
    update MONEY_TABLE set AMOUNT = {amount};
    
  • 説明:トランザクションBがselect文を実行すると待機し、Aコミット後、トランザクションB select文はロックを取得し、amount=1100(Aコミットの結果)
  • が検出される.

    2.3方法三:楽観ロック

  • 取引A
  • select  AMOUNT,VERSION as amount from MONEY_TABLE;
    amount -= 100
    version +=1;
    update MONEY_TABLE set AMOUNT = {amount},VERSION={version} WHERE VERSION <{version};
    

    2.4方法四:増分更新(推奨)

  • 取引A
  • update MONEY_TABLE set AMOUNT = AMOUNT-{changeAmount};
    
  • 説明:Bが先に提出し、Aがupdateを実行するときamountは900で、900に基づいて更新し、結果は1000
  • である.