开发者

simple optimistic lock question in jpa/spring/hibernate

I am trying to implement a basic optimistic lock mechanism with a retry interceptor.

So the thing is there is a object Quiz with a property responsesCount. In case that there is a optimistic Lock exception thrown during an update of the quiz, the respective update method will be invoked again from the retry interceptor.

The thing is that something is not right because the retried method has the same version number number every time, and because of this it will fail the transaction no matter what.

version: 10

process A: start update quiz, version 10 process B: start update quiz, version 10 process B: finish update quiz, version 11 process A: optimistic exception thrown raised update quiz, retry process A inside the retried method the version is always 10

What can I do then? It should increment automatically the version 开发者_C百科in order to success the transaction


An optimistic lock exception is handled like this:

First re-read the record, getting the new version number and the updated field values which the conflicting transaction wrote.

Then reapply your operation, based on the new values. In your case this is simple -- incrementing a value is order-independent or commutative. Other operations might not be simple to reapply -- for example, suppose the transactions were both trying to move a bug in an issue tracker from one workflow state to another. This transition can only happen once, so the retrying transaction would need to check that the bug was still in a valid state for that transition, and if not it would report an error to the user.


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜