【问题标题】:JPA optimistic locking vs synchronized Java methodJPA 乐观锁定与同步 Java 方法
【发布时间】:2016-03-12 23:41:27
【问题描述】:

使用 JPA 乐观锁定,我们可以通过 @Version 字段来控制数据库表是否同时被另一个事务更新,从而允许将可靠的数据存储在数据库中。

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

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

【问题讨论】:

    标签: java database hibernate jpa transactions


    【解决方案1】:

    方法同步的缺点:

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

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

      • 使用悲观锁正是我们尝试做的,因为我们部署了多集群/节点应用程序,因此“同步”不是一个选项。您能指出我们的解决方案吗?您提供的链接范围很广...
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-12
      • 2012-11-14
      • 1970-01-01
      • 2018-10-22
      • 2016-09-23
      • 2021-09-27
      • 2017-10-02
      相关资源
      最近更新 更多