With JPA, we can use manually OPTIMISTIC
or PESSIMISTIC
locking to handle entity changes in transactions.
I wonder how JPA handles locking
Due to JPA 2.1 FR
3.2 Version Attributes
The Version field or property is used by the persistence provider to perform optimistic locking. It is accessed and/or set by the persistence provider in the course of performing lifecycle operations on the entity instance. An entity is automatically enabled for optimistic locking if it has a property or field mapped with a Version mapping.
So if the entity is a versioned object, such as a @Version has been specified, then the default persistence provider will perform optimistic locking.
In the specification persistence_2.0, page 89:
If a versioned object is otherwise updated or removed, then the implementation must ensure that the requirements of LockModeType.OPTIMISTIC_FORCE_INCREMENT are met, even if no explicit call to EntityManager.lock was made.
I've scanned through section 3.4.4 Lock Modes of the Java Persistence API 2.0 Final Release specification and while I couldn't find anything specific (it doesn't state that this is the default or anything like that) there is a footnote which says the following.
The lock mode type NONE may be specified as a value of lock mode arguments and also provides a default value for annotations.
The section is about the kinds of LockModeType values available and their usages and describes which methods takes an argument of this kind and whatnot.
So, as it said LockModeType.NONE
is default for annotations (JPA, annotations left and right) I guess when you use EntityManager.find(Class, Object)
the default LockModeType
is used.
There are some other, subtle, hints to reinforce this. Section 3.1.1 EntityManager interface.
The find method (provided it is invoked without a lock or invoked with LockModeType.NONE) and the getReference method are not required to be invoked within a transaction context.
It makes sense. For example if you use MySQL as your database and your database engine of choice is InnoDB then (by default) your tables will use REPEATABLE READ, if you use some other RDBMS or other database engines this could change.
Right now I'm not exactly sure that isolation levels has anything to do with JPA lock modes (although it seems that way), but my point is that different database systems differ so JPA can't decide for you (at least according to the specification) what lock mode to use by default, so it'll use LockModeType.NONE
if you don't instruct it otherwise.
I've also found an article regarding isolation levels and lock modes, you might want to read it.
Oh, and to answer your last question.
If we don't define an explicit locking mode, can the database integrity be lost?
It depends, but if you have concurrent transactions then the answer is probably yes.