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?
所以我的问题是,这些场景之间有什么区别?是否存在任何性能优势甚至最佳实践?
2 个解决方案
#1
2
Drawbacks of method synchronization:
方法同步的缺点:
- 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.
- 您将序列化属于该实体类的所有实体实例的更新。两个并发线程将无法更新两个不同的实例。
- It does not work in cluster.
- 它在群集中不起作用。
- 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.
- 维护更加困难。如果对实体的操作变得更加复杂,因此可以在多个服务中更新实体,或者您需要在同一事务中更新不同的此类实体类的实例,则必须同步它们。
- Point 3) increases the chances for deadlocks.
- 第3点)增加了死锁的可能性。
- 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.
- 您必须确保执行包含必要同步锁的整个事务,否则,如果在提交事务之前释放锁,则并发事务可能会获取锁并继续更改相同的数据。
- 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).
- 根据用例,即使线程/事务不是并发的,没有版本控制,您也不知道数据是否在此期间发生了变化(例如,您获取数据,根据数据修改客户端上的内容,然后是其他人更改该数据,然后保存您的修改)。
#2
1
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.
- 乐观锁只是为了保证没有不一致的数据库状态(防止在不知不觉中覆盖数据),但它不能保证你不会得到一个无法更改db行的OptimisticLockException。因此,乐观锁具有更好的性能。
- 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
#1
2
Drawbacks of method synchronization:
方法同步的缺点:
- 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.
- 您将序列化属于该实体类的所有实体实例的更新。两个并发线程将无法更新两个不同的实例。
- It does not work in cluster.
- 它在群集中不起作用。
- 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.
- 维护更加困难。如果对实体的操作变得更加复杂,因此可以在多个服务中更新实体,或者您需要在同一事务中更新不同的此类实体类的实例,则必须同步它们。
- Point 3) increases the chances for deadlocks.
- 第3点)增加了死锁的可能性。
- 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.
- 您必须确保执行包含必要同步锁的整个事务,否则,如果在提交事务之前释放锁,则并发事务可能会获取锁并继续更改相同的数据。
- 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).
- 根据用例,即使线程/事务不是并发的,没有版本控制,您也不知道数据是否在此期间发生了变化(例如,您获取数据,根据数据修改客户端上的内容,然后是其他人更改该数据,然后保存您的修改)。
#2
1
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.
- 乐观锁只是为了保证没有不一致的数据库状态(防止在不知不觉中覆盖数据),但它不能保证你不会得到一个无法更改db行的OptimisticLockException。因此,乐观锁具有更好的性能。
- 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