@Transactional アノテーションだけでコードとトランザクションの実行を管理する方法について質問があります。正しくセットアップされた Spring アプリケーションと次のコードがあるとします。
@Transactional
public void withdraw(int amount) {
if(isEnoughFunds(amount)) {
decreaseFunds(amount);
}
}
次のシナリオが発生する可能性はありますか。
- 資金 == 100; 金額 == 100
- スレッド A が撤回に入る / トランザクション A が開始する
- スレッド A は、true と評価される isEnoughFunds を実行します
- スレッド B が撤回に入る / トランザクション B が開始する
- スレッド B は、true と評価される isEnoughFunds を実行します。
- スレッド A は reduceFunds を実行します / スレッド A は db レコードをロックします
- スレッド B は、スレッド A がトランザクションをコミットして書き込みロックを解放するのを待ちます。
- スレッド A が撤退を終了する / トランザクション A がコミットする
- スレッド B は reduceFunds を実行します / スレッド B は db レコードをロックします
- スレッド B は撤退を終了する / トランザクション B はコミットする
- 資金 == -100
これが可能である場合、どのようにそれを防ぎますか?