users@glassfish.java.net

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

From: <glassfish_at_javadesktop.org>
Date: Mon, 10 Nov 2008 08:23:18 PST

My understanding is as follows:

- The first time you read some object from the database, it gets added into the first-level cache.

- Any subsequent reads of that same object will return the instance in the cache

- The object has a "version" associated with it, for optimistic locking. So if you invoke a read-lock on the object what happens is that at commit time JPA ensures that the object still has the same version number.

- Here are the hole in this logic: If you're using READ_COMMITTED transaction isolation then there is a time between the beginning of transaction and the time the object is read where it could have been modified and the read lock will not help you. Then again, read locks aren't supposed to help in this case anyway. They are only supposed to ensure that the object remains unchanged since the first time you read it.

- Now, as to your specific example. I think you are wrong that it is an example of a dirty-read. Remember that from the point of view of the database, all of the operations take place at commit time. There is no "interleaving" of operations as you listed them. Here is what the database actually sees:

T2: R(reads E)
T2: commit
T1: W(edit some entity E)
T1: lock(E)
T1: commit

- Here is an example of a real dirty read:

T1: read E
T2: read E
T2: modify E
T2: commit
T1: modify D based on E's value <-- mistake resulting from a dirty-read
T1: commit

- If you were to "T1: lock(E)" then when T1 goes to commit JPA would throw an exception notifying it if the dirty-read.

I hope this answers your question.

Gili
[Message sent by forum member 'cowwoc' (cowwoc)]

http://forums.java.net/jive/thread.jspa?messageID=315811