JPA乐观锁定与同步Java方法

时间:2016-03-12 23:41:27

标签: java database hibernate jpa transactions

使用JPA乐观锁定,我们可以通过@Version字段进行控制,如果数据库表已被另一个事务同时更新,则允许将可靠数据存储在数据库中。

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

所以我的问题是,这些场景之间有什么区别?是否存在任何绩效优势甚至最佳实践?

2 个答案:

答案 0 :(得分:2)

方法同步的缺点:

  1. 您将序列化属于该实体类的所有实体实例的更新。两个并发线程将无法更新两个不同的实例。
  2. 它在群集中不起作用。
  3. 维护更困难。如果对实体的操作变得更加复杂,因此可以在多个服务中更新实体,或者您需要在同一事务中更新不同的此类实体类的实例,则必须同步它们。
  4. 第3点)增加了死锁的可能性。
  5. 您必须确保执行包含必要同步锁的整个事务,否则,如果在提交事务之前释放锁,则并发事务可能会获取锁并继续更改相同的数据。
  6. 根据用例,即使线程/事务不是并发的,没有版本控制,您也不知道数据是否在此期间发生了变化(例如,您获取数据,根据数据修改客户端上的内容,然后别人改变了那些数据,然后保存你的修改。

答案 1 :(得分:1)

将同步视为悲观锁定:您必须在开始工作之前保留锁定,而不是仅在完成工作时检查是否违反了锁定(提交期间的乐观锁定)。 这两者的目的非常不同:

  • 乐观锁只是为了保证没有不一致的数据库状态(防止在不知不觉中覆盖数据),但它不保证你不会得到一个无法更改db行的OptimisticLockException。因此,乐观锁具有更好的性能。
  • 悲观锁定保证您永远不会写一行,并且您将知道它的最新值(只要您在使用此实体的任何地方进行同步)

一般情况下:不要使用同步来锁定实体,JPA中存在悲观锁定支持锁定实际数据库行:http://docs.oracle.com/javaee/6/tutorial/doc/gkjiu.html