通常、このような同時実行性の問題の解決策には、トランザクションと楽観的なロックが含まれます。 :カウンターを更新するときに、where
を追加します 古い値をチェックし、更新された行数をカウントする句。
v = select value from counter where id=x.
update counter set value = v+1 where value = v and id=x
その間にカウンターが更新された場合、更新によって行が変更されることはありません。そのため、ロールバックしてトランザクションをもう一度試す必要があることがわかります。
1つの問題は、競合が高くなる可能性があることです。 、成功するトランザクションはわずかで、失敗するトランザクションはたくさんあります。
その場合は、悲観的なロックに固執する方がよい場合があります。 、最初に行をロックしてから更新します。しかし、ベンチマークだけが教えてくれます。
編集
楽観的なロックなしでトランザクションを使用すると、次のシナリオが発生する可能性があります。
Max authorized = 50. Current value = 49.
T1: start tx, read value --> 49
T2: start tx, read value --> 49
T1: update value --> 50, acquire a row lock
T1: commits --> release the lock
T2: update value --> 50, acquire a row lock
T2: commits --> release the lock
両方のトランザクションが成功し、値は50ですが、不整合があります。