バージョンベースの楽観的ロックが「last-commit-wins」の問題と適切なオーバーライドを防ぐ方法を理解しようとすると、問題が発生します。
質問をより具体的にするために、JDBC を使用する次の疑似コードを考えてみましょう。
connection.setAutoCommit(false);
Account account = select(id);
if (account.getBalance() >= amount) {
account.setBalance(account.getBalance() - amount);
}
int rowsUpdated = update(account); // version=:oldVer+1 WHERE version=:oldVer
if (rowsUpdated == 0) throw new OptimisticLockException();
connection.commit();
ここで、更新とコミットの間に他のトランザクションがその変更をコミットするとどうなるでしょうか? トランザクションが並行している場合、最初のトランザクションによって行われた更新はまだコミットされていないため、(適切な分離レベルで) 2 番目のトランザクションには表示されないため、最初のトランザクションのコミットは、通知や通知なしに 2 番目のトランザクションの変更をオーバーライドします。エラー。
これは、楽観的ロックが問題の可能性を減らすだけで、一般的にそれを防ぐわけではないということですか?