简体   繁体   English

JPA乐观锁定与同步Java方法

[英]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. 使用JPA乐观锁定,我们可以通过@Version字段控制数据库表是否已被另一个事务同时更新,从而可以将可靠的数据存储在数据库中。

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. 如果Java应用程序只有一个CRUD服务负责数据库中的特定实体,我们可以同步其方法并管理信息在数据库中存储的顺序。

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. 乐观锁仅用于确保没有不一致的数据库状态(防止在不知不觉中覆盖数据),但不能保证您不会因更改db行失败而无法获得OptimisticLockException。 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 通常:不要使用同步来锁定实体,JPA中提供了悲观锁定支持,可以锁定实际的数据库行: http : //docs.oracle.com/javaee/6/tutorial/doc/gkjiu.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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