openjpa-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Michael Dick <>
Subject Re: Problem/ understanding Optimistic Locking and Isolation Levels
Date Thu, 12 May 2011 13:54:41 GMT
Hi Tim,

Optimistic locking is really intended to work with a 'lighter' isolation
level. The JPA spec itself assumes that you'll be using ReadCommitted.

Near the end of your email (third paragraph from the last one) you're on the
right track. Optimistic locking is intended to avoid database level locks
when using a 'lighter' isolation level (Read Committed). It does that by
throwing an exception when it detects that another transaction has modified
the data.

Optimistic Locking isn't really intended to prevent phantom reads.

That said, I wasn't aware that it would affect the TransactionIsolation
property. If you enable openjpa logging, is there anything interesting in
the output?

Here's the property to enable all logging :
<property name="openjpa.Log" value="defaultLevel=TRACE"  />

Hope this helps,

On Thu, May 12, 2011 at 2:57 AM, tfriess <> wrote:

> Hello,
> I think I have a problem understanding how the concepts of Optimistic
> Locking and Isolation Levels work together in OpenJPA.
> Maybe someone can help me understand this in detail! :)
> What my problem of understanding is:
> If a Transaction is in the Isolation Level "serializable", it will see the
> database in a state as it was before the Transaction was started. (And
> changes made within this transaction will be visible to other transactions
> only after a commit.)
> When I use the Optimistic Locking in OpenJPA the behaviour seems to violate
> against this assumption.
> I made two little tests to "proof" this.
> My configuration: I run this tests using OpenJPA 1.2.2 and also OpenJPA
> 2.0.1. The database is hsqldb 2.0.1.
> I activated the Optimistic Level with <property name="openjpa.Optimistic"
> value="true"/> and the isolation level with
> <property name="openjpa.jdbc.TransactionIsolation" value="serializable"/>
> I have caching deactivated by <property name="openjpa.DataCache"
> value="false"/> and
> <property name="openjpa.QueryCache" value="false"/>
> In my first test I have one thread starting a transaction and sending a
> query "SELECT COUNT(a) FROM A a" a few times to the database,
> with some sleep time between each request (using Thread.sleep). After the
> few reads, the transaction is committed.
> Meanwhile another thread also starts a transaction, creates and persists
> such a new A and committes.
> (Right, I check for a phantom read.) What I expect is that the first
> transaction returns every time the same number for its count request, even
> if meanwhile another transaction has inserted a new record.
> But as soon as the second transaction has committed, the first transaction
> gets the new number of objects, which is a phantom read in my eyes and
> shouldn't happen
> within transactions using the isolation level "serializable".
> The second test works on a little parent - children relationship. I have a
> class A which has a "List children" as a field, while the Class B has a "A
> parent" field. I configured a bi-directional relationship:
> For class A (parent):
> <one-to-many name="children" mapped-by="parent" fetch="LAZY">
> <cascade><cascade-all /></cascade>
> </one-to-many>
> And in B (child):
> <many-to-one name="parent" fetch="LAZY" />
> Within one thread I start a transaction and fetch a concrete B entity by
> its
> unique id out of the database. Then the thread sleeps for some time and
> then calls "A theA = b.getParent()" to get a reference to A (lazy load).
> Then the transaction is commited.
> Meanwhile another thread will delete the A record from the database (note:
> the first transaction was started before A was deleted).
> In an serializable isolation level I expect that the first transaction is
> still able to read A from the database, even if meanwhile another
> transaction
> has deleted A. But A is also deleted for the first transaction, in fact I
> get a NullPointerException when the getParent() method is called.
> If I use pessimistic locking instead (<property name="openjpa.Optimistic"
> value="false"/>) it works as expected.
> (I can really see the differences between the isolation levels here. For
> example with the isolation level "read committed" it behaves as described
> above,
> which is ok for this isolation level.)
> So I assume I don't really get the idea behind the optimistic locking? I
> thought "optimistic locking" would only mean that transactions are not
> really blocked
> when working on data, but it could be possible that they must be rolled
> back
> when OpenJPA detects during its commit, that another transaction has also
> made changes to the same data. I have not read anywhere, that there is no
> serializable isolation level available for optimistic locking...
> Can someone please help me understanding this?
> Besides that I also have other question:
> What is the difference between the openjpa.Optimistic property and the
> openjpa.LockManager property? Do they depend on each other? What happens if
> I set
> openjpa.Optimistic=true and openjpa.LockManager=pessimistic? I think this
> is
> a caveat?
> I really would appreciate, if someone could help me.
> Thank you very much!
> Kind regards,
> Tim
> --
> View this message in context:
> Sent from the OpenJPA Users mailing list archive at

  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message