0

バージョンベースの楽観的ロックが「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 番目のトランザクションの変更をオーバーライドします。エラー。

これは、楽観的ロックが問題の可能性を減らすだけで、一般的にそれを防ぐわけではないということですか?

4

1 に答える 1

0

データベースの「トランザクション」の考え方は、複数の概念的な操作にわたって「一貫性」の保証を提供することになっています。データベースがこれを強制します。そのため、トランザクションがコミットされると、データベースは、トランザクション中に発生したすべてのことが引き続き有効であることを保証できる場合にのみ、トランザクションの完了を許可する必要があります。

実際には、データベースは通常、更新の 1 つが成功すると、関連するトランザクションが完了するまで関連する行が書き込みロックされるようにこれを処理します。したがって、更新の 1 つが失敗することが保証されます。

注: これには、jdbc 接続に適切な分離レベルも必要です。分離レベルにより、更新前に行われた現在の値のテストが、書き込み時にも適用できることが保証されます。

于 2014-07-15T16:45:51.410 に答える