【问题标题】:Concurrent updates of same entity同一实体的并发更新
【发布时间】:2014-03-13 10:52:00
【问题描述】:

先生们/女士们,

我遇到了同一实体的并发更新问题。

进程 1 获得对象的集合。为了性能,这个过程不使用 Hibernate 来检索数据,这对我来说听起来有点牵强。此过程还使用 Hibernate 更新集合中某些对象的某些字段。

进程 2 获得了一个类似于集合中的一个对象(基本上是 DB 中的同一行)并以某种方式对其进行更新。此过程使用 Hibernate。

由于进程 1 和进程 2 互不了解,它们可以更新同一个实体,使其处于不一致状态。

例如:

  1. 进程1获取集合
  2. 进程 2 获得一个实体并删除它的一些属性以及它链接到的实体
  3. 进程 1 返回并尝试保存该实体并获取实体未找到异常

我需要处理这种情况。

那么有什么办法呢?

目前我看到了两种方法:

  1. 在数据库之上创建层,该层将跟踪系统中的每个实体,有效地禁止创建同一实体的多个实例
  2. 设置乐观锁,由于某些实体不是 Hibernate 获得的,我需要以某种不同的方式实现它

任何想法都会很有帮助

提前致谢

【问题讨论】:

  • 我会选择 2。我自己也在进程 1 中应用 hibernate/JPA。事实上,如果我不得不猜测的话,为了性能而不使用 Hibernate 是一个非论点,它是由过早优化提供的。请注意应用乐观锁定的后果:并发修改将导致只有一个线程成功,而所有其他线程都失败并出现异常。
  • @Gimby 我完全同意你对休眠的看法。我只是还不能说服我的老板。我宁愿得到有意义的并发更新异常并处理它而不是意外的实体未找到异常。

标签: java multithreading hibernate jpa


【解决方案1】:

由于进程 1 和进程 2 互不了解,它们可以更新同一个实体,使其处于不一致状态。

我会重新表述:两个进程都可以更新相同的数据。只有 Hibernate 会知道实体,而其他进程似乎通过 JDBC 访问数据。

我会选择选项 2,这将涉及您的实体中的版本列。 然后 IIRC Hibernate 将在查询中添加 WHERE version = x 条件并检查是否所有行都已更新,如果没有,将抛出 OptimistictLockException。您可以在 JDBC 查询中执行相同的操作,即 UPDATE ... SET ... version = x + 1 ... WHERE version = x AND additionalConditions 并检查 JDBC 返回的更新行数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多