http://blog.csdn.net/terry_long/article/details/54291455
JPA 2.0 adds 6 new lock modes, of which two are optimistic locks. JPA 2.0 also allows pessimistic locks and adds 3 kinds of pessimistic locks, and the 6th lock mode is unlocked.
The following are the new two optimistic lock modes: 1, optimistic: it is the same as read lock mode, JPA 2.0 still supports the Read lock mode, but it is clear that the use of optimistic is recommended in new applications. 2, Optimistic_force_increment: It is the same as the Write lock mode, JPA 2.0 still supports the Write lock mode, but it is clear that the use of Optimistic_force_increment is recommended in new applications.
The following are the new three pessimistic lock modes: 1, Pessimistic_read: As long as the transaction reads the entity, the Entity Manager locks the entity until the transaction completes the lock, and uses this lock mode when you want to query the data using repetitive read semantics, in other words, This lock mode does not prevent other transactions from reading data when you want to ensure that the data is not modified during continuous reading. 2, Pessimistic_write: As long as the transaction update entity, the entity Manager will lock the entity, this lock mode forces an attempt to modify the transaction serialization of entity data, when multiple concurrent update transactions have a higher probability of update failure to use this lock mode. 3. Pessimistic_force_increment: When the transaction reads the entity, the Entity Manager locks the entity, and when the transaction ends, the version attribute of the entity is added, even if the entity is not modified.
The last one is none, which is no lock.
You can specify the lock mode by @lock annotation, let's take a look at the @lock annotation Source:
[Java] View plain copy @Target ({elementtype.method, elementtype.annotation_type}) @Retention (retentionpolicy.runtime @Documented public @interface Lock {/** * @link Lockmodetype} to is used when executing the ANN otated query or CRUD method. * * @return/Lockmodetype value (); }
Lockmodetype is the enumeration that specifies the pattern, look at its source code: [Java] View plain copy public enum lockmodetype { /** * synonymous with <code >OPTIMISTIC</code>. * <code>optimistic</code > is to be preferred for new * applications. * */ READ, /** * synonymous with <code>optimistic_force_increment</code>. * <code>optimistic_force_imcrement</code> is to be preferred for new * applications. * */ WRITE, /** * Optimistic lock. * * @since java persistence 2.0 */ OPTIMISTIC, /** * Optimistic lock, with version update. * * @since Java Persistence 2.0 */ OPTIMISTIC_FORCE_INCREMENT, /** * * Pessimistic read lock. * * @since Java Persistence 2.0 */ PESSIMISTIC_READ, /** * Pessimistic write lock. * * @since java persistence 2.0 */ PESSIMISTIC_WRITE, /** * pessimistic write lock, with version update. * * @since Java Persistence 2.0 */ PESSIMISTIC_FORCE_INCREMENT, /** * No lock. * * @since Java Persistence 2.0 */ NONE }
To write a simple example (incomplete code): @Lock annotations need to be added to the repository layer, which is the DAO layer of Hibernate, as follows: [Java] View plain copy public interface Testrepository Extends Jparepository<testobject, String>, jpaspecificationexecutor<testobject> { @Lock (value = lockmodetype.pessimistic_read) @Query (value = "Select O testobject where o.id=: id") Publ IC Testobject getbyidforupdate (@Param ("id") long ID); }
Here we use the @query annotation, just define the interface, and spring will automatically generate the implementation based on the HQL statement in the annotation. The call to the repository is generally placed on the service layer, the calling method must be wrapped by the transaction, or the startup will be an error. [Java] View plain copy public interface mytestservice{ /** * definition interface */ Public testobject updateobjstatus (long id,string status); } public class mytestserviceimpl{ @Autowired private testrepository repos; /** * Implementation of a lock Update method */ @ transactional @Override public testobject updateobjstatus (long id,string status) { testobject obj = repos.getbyidforupdate (ID); if (null == obj ) { throw new runtimeexception ("testobject id = " +id + ", Not found. "); } if (Status.equals (Obj.getstatus ()) { throw new RuntimeException ("testobject id = "+id+", Status is alread be: "+status+", update fail! "); } obj.setstatus (status); repos.save (obj); } }
In the above example, we try to update the status of the Testobject object, before updating the data query to add row-level locks, to ensure that a thread at the time of the update will not be modified by other threads, the update is also judged before, if the data has been updated to run out of the exception to end the update This way, when multiple threads are updating the Testobject object at the same time, only one thread will eventually update successfully.