jpa / spring / hibernate中的简单乐观锁定问题

时间:2011-03-01 11:01:41

标签: mysql hibernate spring jpa optimistic-locking

我正在尝试使用重试拦截器实现基本的乐观锁定机制。

所以事情是有一个带有属性respondCount的对象测验。如果在更新测验期间抛出了乐观的Lock异常,则将再次从重试拦截器调用相应的更新方法。

事情是某些事情是不对的,因为重试的方法每次都有相同的版本号,因此无论如何都会使事务失败。

版本:10

流程A: 开始更新测验,版本10 过程B: 开始更新测验,版本10 过程B: 完成更新测验,版本11 过程A: 抛出更新测验的乐观异常,重试过程A. 在重试方法中,版本总是10

那我该怎么办?它应该自动增加版本以使事务成功

3 个答案:

答案 0 :(得分:1)

在我看来,你想要更新quizz,即使其他人已经在你背后更新它(这会引发乐观的例外)。如果是这种情况,为什么要在此实体上启用乐观登录?只需删除版本字段,即使没有重试也可以。

如果你真的想保留版本字段,那么更改方法以便从DB获取quizz,将新加载的quizz的版本号复制到分离的实例,然后合并分离的实例以复制所有附加值的新值。

答案 1 :(得分:1)

乐观锁异常的处理如下:

首先重新读取记录,获取冲突事务所写的新版本号和更新的字段值。

然后根据新值重新应用您的操作。 在您的情况下,这很简单 - 递增值是与顺序无关或可交换的。其他操作可能不容易重新应用 - 例如,假设事务都试图将问题跟踪器中的错误从一个工作流状态移动到另一个工作流状态。此转换只能发生一次,因此重试事务需要检查错误是否仍然处于该转换的有效状态,如果不是,则会向用户报告错误。

答案 2 :(得分:0)

你试图打败乐观的锁定:D,提出了一个问题:你需要乐观的锁吗?

我唯一可以看到重试的方法是在不丢失以前的数据的情况下刷新对象,然后再次应用更改......无论如何,你要覆盖数据,这违背了乐观的锁。

在你的情况下,我要么完全禁用乐观锁定,要么将计数放在一个辅助表中,而不是乐观锁定。