You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@openjpa.apache.org by Miłosz Tylenda <mt...@o2.pl> on 2008/11/11 18:38:56 UTC

Re: How does an explicit EntityManager.lock() call prevent dirty readsin JPA

Vlad,

Maybe the cited sentence is not correct? It says:

> The lock() API acquires an optimistic lock, not a pessimistic lock. It means
> that the version will be checked, or updated on commit, it does not matter
> when it is called in the transaction, as the check occurs on commit 

But if you read the JPA spec it says exactly what you have read in the JavaDoc but also adds:

"This will generally be achieved by the entity manager acquiring a lock on the underlying database row.
Any such lock may be obtained immediately (so long as it is retained until commit completes), or the
lock may be deferred until commit time (although even then it must be retained until the commit com-
pletes). Any implementation that supports repeatable reads in a way that prevents the above phenomena
is permissible."

I understand from this that an implementation can do a SELECT FOR UPDATE for a lock() instead of being restricted to optimistic concurrency control.

Greetings,
Milosz



> Hi, 
> 
> i'm trying to understand the behaviour of the EntityManager.lock() call. 
> The Sun documentation (
> http://java.sun.com/javaee/5/docs/api/javax/persistence/LockModeType.html) 
> on this is a bit confusing for me and i will explain why. It says that if T1
> calls EntityManager.lock() on an entity, then T2 couldn't make a dirty read. 
> Also i read here (http://www.nabble.com/JPA-locking-td19525631.html) that " 
> The lock() API acquires an optimistic lock, not a pessimistic lock. It means
> that the version will be checked, or updated on commit, it does not matter
> when it is called in the transaction, as the check occurs on commit 
> " 
> So it does not matter when the lock call is made. Ok, now let's imagine the
> following typical scenario of the dirty read in a time-point follow-up: 
> T1                                           T2 
> --------------------------------------------------- 
> T1: W(edit some entity E) 
>                                               T2: R(reads E) 
>                                               T2: commit 
> T1: lock(E) 
> T1: commit 
> --------------------------------------------------- 
> So there is nothing from preventing T2 to commit in this concurrent
> transaction scenario and thus making a dirty read. 
> So my guess is: 
> - either the javadoc would be wrong presenting that T1 is the one doing the
> lock() call instead of T2 doing it. 
> - or the lock() call moment is infact important and, in this case, doing it
> before the W(edit) in T1 should solve the problem. 
> Would be nice to give the insights on how this works. Thanks. 
> 
> Vlad 
> -- 
> View this message in context: http://n2.nabble.com/How-does-an-explicit-EntityManager.lock%28%29-call-prevent-dirty-reads-in-JPA-tp1480410p1480410.html
> Sent from the OpenJPA Developers mailing list archive at Nabble.com.
> 
> 

Re: How does an explicit EntityManager.lock() call prevent dirtyreadsin JPA

Posted by Miłosz Tylenda <mt...@o2.pl>.
Vlad,

I agree with your thinking on your scenario. That's why I think you need row locking in the database and it matters when you call lock() in order to prevent T2's dirty read.

Greetings,
Milosz


> Hello Milozs,
> 
> thanks for your reply. Maybe you are right, anyway, pls comment on my
> scenario. There is nothing preventing T2 from commiting with a dirty read;
> the lock() call doesen't even get the chance to be called.
> 
> Waiting for your opinion.
> 
> 
> Miłosz Tylenda wrote:
> > 
> > Vlad,
> > 
> > Maybe the cited sentence is not correct? It says:
> > 
> >> The lock() API acquires an optimistic lock, not a pessimistic lock. It
> >> means
> >> that the version will be checked, or updated on commit, it does not
> >> matter
> >> when it is called in the transaction, as the check occurs on commit 
> > 
> > But if you read the JPA spec it says exactly what you have read in the
> > JavaDoc but also adds:
> > 
> > "This will generally be achieved by the entity manager acquiring a lock on
> > the underlying database row.
> > Any such lock may be obtained immediately (so long as it is retained until
> > commit completes), or the
> > lock may be deferred until commit time (although even then it must be
> > retained until the commit com-
> > pletes). Any implementation that supports repeatable reads in a way that
> > prevents the above phenomena
> > is permissible."
> > 
> > I understand from this that an implementation can do a SELECT FOR UPDATE
> > for a lock() instead of being restricted to optimistic concurrency
> > control.
> > 
> > Greetings,
> > Milosz
> > 
> > 
> > 
> >> Hi, 
> >> 
> >> i'm trying to understand the behaviour of the EntityManager.lock() call. 
> >> The Sun documentation (
> >> http://java.sun.com/javaee/5/docs/api/javax/persistence/LockModeType.html) 
> >> on this is a bit confusing for me and i will explain why. It says that if
> >> T1
> >> calls EntityManager.lock() on an entity, then T2 couldn't make a dirty
> >> read. 
> >> Also i read here (http://www.nabble.com/JPA-locking-td19525631.html) that
> >> " 
> >> The lock() API acquires an optimistic lock, not a pessimistic lock. It
> >> means
> >> that the version will be checked, or updated on commit, it does not
> >> matter
> >> when it is called in the transaction, as the check occurs on commit 
> >> " 
> >> So it does not matter when the lock call is made. Ok, now let's imagine
> >> the
> >> following typical scenario of the dirty read in a time-point follow-up: 
> >> T1                                           T2 
> >> --------------------------------------------------- 
> >> T1: W(edit some entity E) 
> >>                                               T2: R(reads E) 
> >>                                               T2: commit 
> >> T1: lock(E) 
> >> T1: commit 
> >> --------------------------------------------------- 
> >> So there is nothing from preventing T2 to commit in this concurrent
> >> transaction scenario and thus making a dirty read. 
> >> So my guess is: 
> >> - either the javadoc would be wrong presenting that T1 is the one doing
> >> the
> >> lock() call instead of T2 doing it. 
> >> - or the lock() call moment is infact important and, in this case, doing
> >> it
> >> before the W(edit) in T1 should solve the problem. 
> >> Would be nice to give the insights on how this works. Thanks. 
> >> 
> >> Vlad 
> >> -- 
> >> View this message in context:
> >> http://n2.nabble.com/How-does-an-explicit-EntityManager.lock%28%29-call-prevent-dirty-reads-in-JPA-tp1480410p1480410.html
> >> Sent from the OpenJPA Developers mailing list archive at Nabble.com.
> >> 
> >> 
> > 
> > 
> 
> -- 
> View this message in context: http://n2.nabble.com/How-does-an-explicit-EntityManager.lock%28%29-call-prevent-dirty-reads-in-JPA-tp1480410p1486495.html
> Sent from the OpenJPA Developers mailing list archive at Nabble.com.
> 
> 

Re: How does an explicit EntityManager.lock() call prevent dirty readsin JPA

Posted by vladbalan <vl...@gmail.com>.
Hello Milozs,

thanks for your reply. Maybe you are right, anyway, pls comment on my
scenario. There is nothing preventing T2 from commiting with a dirty read;
the lock() call doesen't even get the chance to be called.

Waiting for your opinion.


Miłosz Tylenda wrote:
> 
> Vlad,
> 
> Maybe the cited sentence is not correct? It says:
> 
>> The lock() API acquires an optimistic lock, not a pessimistic lock. It
>> means
>> that the version will be checked, or updated on commit, it does not
>> matter
>> when it is called in the transaction, as the check occurs on commit 
> 
> But if you read the JPA spec it says exactly what you have read in the
> JavaDoc but also adds:
> 
> "This will generally be achieved by the entity manager acquiring a lock on
> the underlying database row.
> Any such lock may be obtained immediately (so long as it is retained until
> commit completes), or the
> lock may be deferred until commit time (although even then it must be
> retained until the commit com-
> pletes). Any implementation that supports repeatable reads in a way that
> prevents the above phenomena
> is permissible."
> 
> I understand from this that an implementation can do a SELECT FOR UPDATE
> for a lock() instead of being restricted to optimistic concurrency
> control.
> 
> Greetings,
> Milosz
> 
> 
> 
>> Hi, 
>> 
>> i'm trying to understand the behaviour of the EntityManager.lock() call. 
>> The Sun documentation (
>> http://java.sun.com/javaee/5/docs/api/javax/persistence/LockModeType.html) 
>> on this is a bit confusing for me and i will explain why. It says that if
>> T1
>> calls EntityManager.lock() on an entity, then T2 couldn't make a dirty
>> read. 
>> Also i read here (http://www.nabble.com/JPA-locking-td19525631.html) that
>> " 
>> The lock() API acquires an optimistic lock, not a pessimistic lock. It
>> means
>> that the version will be checked, or updated on commit, it does not
>> matter
>> when it is called in the transaction, as the check occurs on commit 
>> " 
>> So it does not matter when the lock call is made. Ok, now let's imagine
>> the
>> following typical scenario of the dirty read in a time-point follow-up: 
>> T1                                           T2 
>> --------------------------------------------------- 
>> T1: W(edit some entity E) 
>>                                               T2: R(reads E) 
>>                                               T2: commit 
>> T1: lock(E) 
>> T1: commit 
>> --------------------------------------------------- 
>> So there is nothing from preventing T2 to commit in this concurrent
>> transaction scenario and thus making a dirty read. 
>> So my guess is: 
>> - either the javadoc would be wrong presenting that T1 is the one doing
>> the
>> lock() call instead of T2 doing it. 
>> - or the lock() call moment is infact important and, in this case, doing
>> it
>> before the W(edit) in T1 should solve the problem. 
>> Would be nice to give the insights on how this works. Thanks. 
>> 
>> Vlad 
>> -- 
>> View this message in context:
>> http://n2.nabble.com/How-does-an-explicit-EntityManager.lock%28%29-call-prevent-dirty-reads-in-JPA-tp1480410p1480410.html
>> Sent from the OpenJPA Developers mailing list archive at Nabble.com.
>> 
>> 
> 
> 

-- 
View this message in context: http://n2.nabble.com/How-does-an-explicit-EntityManager.lock%28%29-call-prevent-dirty-reads-in-JPA-tp1480410p1486495.html
Sent from the OpenJPA Developers mailing list archive at Nabble.com.