Sorry if this is a dumb question - I've got an object "Subscription" which I want to edit concurrently. Because when editing subscriptions I also send emails, charge credit cards, etc.. I can't rely on the "OptimisticLockException" that hibernate will throw if the version number is off.
Originally, I just used code like:
Code:
Subscription s = em.get(subId);
em.lock(s, LockModeType.READ);
From this, hibernate issues a "select for update" which will create an exclusive lock on the DB and wait for any concurrent transaction which also wants to write the object to complete before continuing.
However, I still got optimistic lock exceptions. I realized that this must be because even though I'd waited for the other operation to finish, I'm still using the "old" object (em.lock() doesn't update the contents of the object). So, I added this:
Code:
em.refresh(s);
Unfortunately, this introduced a problem where any changes already made to the object will get dumped - for example, I have a shared method that operates on the object, but this shared code should only refresh the object if it was not already locked.
One option I have is to manually manage the "locked" state of the object and only do a lock/refresh if the object has not previously been locked in this transaction. The other option I am considering is to do an em.flush() before the lock/refresh, which would theoretially work since the refresh() would just reload the same data that was flush()ed, however, this also seems potentially quite inefficient.
I'm considering putting a transient boolean inside all my objects that I lock (then they'll have a version number and a boolean) and they can use that to decide whether they've been locked in the current transaction (not sure how best to track this).
How do other handle this locking issue? The way the locks work right now seem to involve a lot of work and there's a lack of warnings about the pitfalls I am falling into one after the other ...
All suggestions and feedback appreciated!