在尝试理解基于版本的乐观锁定如何阻止" 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();
如果其他事务在更新和提交之间提交更改,那该怎么办?如果事务是并发的,那么第一个事务所做的更新尚未提交,因此对第二个事务不可见(具有适当的隔离级别),因此第一个事务提交将覆盖第二个事务的更改而不通知或错误。
这种情况是乐观锁定只是降低了问题的可能性而一般不会阻止它吗?
答案 0 :(得分:0)
数据库“事务”的概念是它应该提供跨多个概念操作的“一致性”保证。数据库负责执行此操作。因此,当事务提交时,数据库应该只允许事务完成,如果它可以确保事务期间发生的所有事情仍然有效。
实际上,数据库通常会对此进行处理,以便一旦其中一个更新成功,相关行将被写入锁定,直到相关事务完成为止。因此,其中一个更新保证失败。
注意:这还需要在jdbc连接中使用适当的隔离级别。隔离级别确保在更新之前完成的当前值的测试在写入时仍然适用。