0

在尝试了解基于版本的乐观锁定如何防止“最后提交获胜”问题和适当的覆盖时,我遇到了困难。

为了使问题更具体,让我们考虑以下使用 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();

在这里,如果其他事务会在更新和提交之间提交其更改怎么办?如果事务是并发的,则第一个事务所做的更新尚未提交,因此对第二个事务不可见(具有适当的隔离级别),因此第一个事务提交将覆盖第二个事务的更改,而无需任何通知或错误。

乐观锁定是否只是降低了问题的可能性,而不是一般地阻止它?

4

1 回答 1

0

数据库“事务”的想法是它应该提供跨多个概念操作的“一致性”保证。数据库负责执行此操作。因此,当事务提交时,数据库应该只允许事务完成,前提是它可以确保事务期间发生的所有事情仍然有效。

在实践中,数据库通常会处理这个问题,一旦其中一个更新成功,相关行将被写锁定,直到相关事务完成。因此,保证其中一个更新会失败。

注意:这还需要在您的 jdbc 连接中设置适当的隔离级别。隔离级别确保在更新之前完成的当前值测试在写入时仍然适用。

于 2014-07-15T16:45:51.410 回答