0

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

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

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

版本:10

进程A:开始更新测验,版本10 进程B:开始更新测验,版本10 进程B:完成更新测验,版本11 进程A:抛出乐观异常引发更新测验,重试进程A在重试方法中版本始终为10

那我能做什么?它应该自动增加版本以使交易成功

4

3 回答 3

1

It seems to me that you want to update the quizz, even if someone else has updated it behind your back (which throws the optimistic exception). If that's the case, why do you enable optimistic logking on this entity? Just remove the version field, and it will work without even retrying.

If you really want to keep the version field, then change the method so that it gets the quizz from DB, copies the version number of the freshly loaded quizz to your detached instance, and then merge the detached instance to copy all the new values to the attached one.

于 2011-03-01T11:24:42.163 回答
1

乐观锁异常的处理方式如下:

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

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

于 2011-03-01T21:42:44.877 回答
0

You're trying to defeat the optimistic lock :D, which raises the question: do you need the optimistic lock?

The only sane way I can see of retrying, without loosing previous data, is to refresh the object and then apply the changes again... in any way, you're going to override data, which goes against the idea of optimistic locks.

In your case, I would either disable optimistic locking at all, or put the count in an ancillary table, without optimistic locking.

于 2011-03-01T11:24:32.357 回答