Have read read the documentation on optimistic locks, still not sure how to deal with these exceptions:
[ObjectDB 2.2.5_04] javax.persistence.RollbackException
Failed to commit transaction: Optimistic lock failed for object
Have read read the documentation on optimistic locks, still not sure how to deal with these exceptions:
[ObjectDB 2.2.5_04] javax.persistence.RollbackException
Failed to commit transaction: Optimistic lock failed for object
perhaps I should explain the problem, which is that the optimistic lock exception fails repeatedly once the object is modified from another process.
ie: process A modifies the object
then process B modifies the object,
then any further transactions from process A get the optimistic lock exception.
ie: the version number does not appear to be automatically updated in process A.
So, do I need to refresh objects before using them?
I would have thought that would be done automatically.
Having used objectdb for nearly 10 years now, all in embedded mode, I'm a bit surprised by its behavior in client/server mode.
Process A cannot be aware to the change in process B automatically - an attempt to apply such automatic updates by ObjectDB would be very inefficient.
But you can do that update explicitly in your application - e.g. by invoking refresh. You may choose to do that only during a second attempt after an optimistic exception (to improve performance).
The behavior has nothing to do with client-server vs. embedded mode. This is how it works in ObjectDB 2.x in both embedded and client-server modes.
But you can disable optimistic locking in the server configuration.
read the documentation, but am still not grokking how to deal with this problem.
are you saying that, for every transaction, I need to handle the optimistic lock by manually refreshing each object?
if so, it seems like a huge amount of code.
questions:
1. is there a way to do this automatically (or alternatively to turn off caching??)
2. do I understand correctly that if object x is modified and persisted by process B, then any attempt to persist it with process A will fail unless object x is first refreshed?
3. what happens if locking version-check is set false? are the changes from process B lost if process A subsequently commits?
4. Would a valid solution be to explicitly refresh any object before I modify it??
Note: In applications that use optimistic locking - it is acceptable to present an error to the user if it tries to commit changes on a document that has been concurrently changed by someone else. If it is not acceptable then refresh is not the solution - since someone can change the object just after the refresh. In that case - use pessimistic locks.
I read this before: "Note: In applications that use optimistic locking - it is acceptable to present an error to the user if it tries to commit changes on a document that has been concurrently changed by someone else. If it is not acceptable then refresh is not the solution - since someone can change the object just after the refresh. In that case - use pessimistic locks"
However, my application runs a time critical state machine, and it's not acceptable to do a round trip to the user, so that doesn't help me. Pessimistic locks might not help either, given #3 above, ie: it seems like last update wins, and changes can be overridden.
So it seems that the best solution for me is to refresh any object before it is modified. Presumably that a blocking operation?
Next question: how do I automatically cascade the refresh (ie for collections held by the object modified)?
Can cascading refresh be set in the conf file?
With pessimistic locks - the object is locked when it is retrieved and no one else can modify it until commit.
Refresh is not blocking - and again, it might not be sufficient to block other users from modifying the object - which means that you still may see optimistic lock exceptions.
Cascading refresh is set by annotations.
sorry for all the questions but this is still unclear to me.
1. optimistic locks: presumably refresh might not help because process B could modify object after process A has refreshed it but before A has committed?
2. pessimistic locks:
a) is the object is globally locked at the database when retrieved from L2 cache ?
b) If process B attempts to modify object after it is retrieved by process A, does process B block, or fail with an exception? If B blocks is there a timeout?
c) to configure pessimistic locking, all I do is set: <locking version-check="false" /> correct? Is that all that is needed to switch from optimistic to pessimistic?
d) If I'm using pessimistic, then does it mean that I don't have to refresh?
e) Is there no way to automatically refresh objects in the L2 cache?
so far the following works for me:
1) standard config file with these changes:
<locking version-check="false" /> <enhancement agent="true" reflection="ignore" />
2) refreshing every object and in every query (whether modified or not), but I'm not annotating cascading refreshes.
ie: I think I have: pessimistic locking + enhancement + refresh on all objects (but no cascading refreshes)
Interestingly I'm noticing no increase in the transaction time (which I measure).
> 1. optimistic locks: presumably refresh might not help because process B could modify object after process A has refreshed it but before A has committed?
Yes.
> 2. pessimistic locks:
> a) is the object is globally locked at the database when retrieved from L2 cache ?
Locks are global at the database levels. The L2 cache is bypassed.
> b) If process B attempts to modify object after it is retrieved by process A, does process B block, or fail with an exception? If B blocks is there a timeout?
Default is immediate failure, timeout can be set - see the documentation.
> c) to configure pessimistic locking, all I do is set: <locking version-check="false" /> correct? Is that all that is needed to switch from optimistic to pessimistic?
No - in JPA pessimistic locks are not automatic - see the documentation.
> d) If I'm using pessimistic, then does it mean that I don't have to refresh?
Yes.
> e) Is there no way to automatically refresh objects in the L2 cache?
You can empty the L2 cache or remove a specific class / object from that cache.