Search code examples
javasqlhibernatejpatransactions

How does JPA @Version annotation works when you have multiple entities


Suppose we are using a DB with isolation level set to: read_committed and we are also using JPA Entities annotated with @Version.

We have two transactions T and K like these:

T ------------------------------------- K
start
read A
read B
read C
-------------------------------------- start
-------------------------------------- update A
-------------------------------------- end
update C
using the states of
object A and B
end

At this point in transaction T the update of C is successful, (version check is fine), so we are updating C using a status that never really existed on the DB.

What's wrong with my understanding ?

EDIT:

@Vlad

Consider this example:

T------------------------------------------------------K

Start transaction
Read A
-----------------------------------------------Start transaction
-----------------------------------------------Mod A
-----------------------------------------------Mod B
-----------------------------------------------End transaction
Read C version = 1
Read B

// use data da A and B
// to update C
A,B -> C
// update is successfull (check version is fine)

End transaction

Using OPTIMISTIC_FORCE_INCREMENT your are basically telling me to use always the find method with this option set right ?


Solution

  • Optimistic locking works for individual table rows only. In this particular case, the entity C can be updated successfully since the second transaction does not modify it.

    If you want to create a conflict here, then you must use either of the following optimistic lock requests:

    This way, in the second transaction, whenever you update the entity A, you'll also trigger a version increment in C.