简体   繁体   中英

JPA optimistic locking vs synchronized Java method

Using JPA optimistic locking we can control via a @Version field if a database table has been updated by another transaction at the same time, allowing to have reliable data stored in database.

If a Java application has only one CRUD service in charge of an specific entity in database, we could synchronize its methods and manage the order the information is stored in database too.

So my question is, what's the difference between those scenarios? Does exist any advantage of performance or even best practices to follow?

Drawbacks of method synchronization:

  1. You will serialize the updates for all of the entity instances belonging to that entity class. Two concurrent threads will not be able to update two different instances.
  2. It does not work in cluster.
  3. Maintenance is more difficult. If the operations with the entity become more complex so it becomes possible to update the entity in multiple services, or you need to update instances of different such entity classes in the same transaction, you will have to synchronize them all.
  4. Point 3) increases the chances for deadlocks.
  5. You will have to ensure to execute the entire transaction holding the necessary synchronization locks, otherwise, if you release the lock before you commit the transaction, a concurrent transaction may obtain the lock and proceed with changing the same data.
  6. Depending on use cases, even if threads/transactions are not concurrent, without versioning you don't know whether the data has changed in the meantime (for example, you fetch data, modify something on the client based on the data, then somebody else changes that data, and then you save your modifications).

Think of synchronization as pessimistic locking: you have to reserve the lock before you start working as opposed to checking if you violated the lock only when you finished working (optimistic lock during commit). The two serve very different purposes:

  • optimistic lock is only there to guarantee there is no inconsistent database state (prevents overwriting data unknowingly) but it does not guarantee you won't get an OptimisticLockException an fail to change the db row. For this reason optimistic lock has much better performance.
  • pessimistic locking guarantees that you will never fail to write a row and you will know its most up to date values (as long as you synchronize everywhere where you use this entity)

In general: do not use synchronization to lock on entities, there is pessimistic lock support in JPA which locks on the actual DB row: http://docs.oracle.com/javaee/6/tutorial/doc/gkjiu.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM