【问题标题】:Hibernate shared entity race conditionsHibernate 共享实体竞争条件
【发布时间】:2013-03-03 17:42:17
【问题描述】:

我有一个问题,如果两个不同的网络用户在同一个实体上工作,会发生什么。 例如一个共享实体有四个字段:

class HibernateSharedEntity
{
int id;
int a;
int b;
int c;
int d;
}

现在,两个用户同时打开了一笔交易。其中一个正在更新该实体,第二个用户正在阅读该实体。以下步骤将更好地解释它:

时间 1:Hibernate 实体存储在数据库中,具有值:a=b=c=d=0 和 id=1。
时间 2:用户 1 开启新交易。
时间 3:User1 读取 id=1 的 HibernateSharedEntity
时间 4:用户 1 正在修改所有字段:例如a=2,b=3,c=4,d=5。
时间 5:User1 正在提交事务。
时间 6:Hibernate 正在更新 a=2
时间 7:Hibernate 正在更新 b=3
时间 8:现在 User2 打开一个新事务并读取这个共享实体。问题: 他找回了什么?他是否获取了一个半更新的实体,例如: a=2 , b=3, c=0, d=0 ?
时间 9:Hibernate 正在更新 c=4
时间 10:Hibernate 正在更新 d=5

我想避免半更新的实例。这是我的应用程序中的一个关键点。 如果第二个用户想要检索这个共享实体,我想要第二个 用户只能在两种状态下读取此共享实体,a=b=c=d=0 状态(提交前)或 a=2,b=3,c=4,d=5 状态(提交后)。我知道休眠可以进行一次插入来更新所有这些值,但在我的应用程序中它似乎更复杂,因为这个共享实体与其他共享实体有关系,也可以由 User1 更新。所以从现在开始,hibernate 不能进行一次插入来更新这两个共享实体。因此,当用户 1 在一个事务中更新更多共享实体时,用户 2 是否有可能以“未同步状态”读取这些实体,我的意思是当一个实体已更新但另一个实体尚未更新时?

我认为它可能很复杂,所以我会尝试更多地解释它: 在我的应用程序中,共享实体必须同步。例如。有两个共享实体,例如:
entity1 = {a=1,b=2,c=3,d=4}
实体2 = {a=5,b=6,c=7,d=8}

现在 User1 想要更新这些实体,例如到这个状态:
entity1 = {a=0,b=0,c=0,d=0}
entity2 = {a=0,b=0,c=0,d=0}

。当 User1 进行更新事务时,User2 想要获取这些共享实例并 我想避免 User2 在这种状态下读取这些实体:
entity1 = {a=0,b=0,c=0,d=0}
entity2 = {a=5,b=6,c=7,d=8}
如您所见,entity1 已更新,但 entity2 未更新。是我申请中的一个临界点,不可能出现这种情况。我怎样才能避免这种情况? hibernate 会解决这个问题吗? 提前谢谢你。

【问题讨论】:

    标签: java hibernate


    【解决方案1】:

    您的第一个场景是不可能的。 Hibernate 在事务提交之前而不是之后将更改写入数据库。用户 2 将读取已提交到数据库的内容,因为它在提交第一个事务后读取实体。如果用户 2 在第一个事务提交之前从数据库中读取,它将读取第一个事务开始之前的状态(只要数据库隔离级别是默认的 READ_COMMITTED)。

    Hibernate 应用程序与其他数据库应用程序没有什么不同:事务的 ACIDity 由数据库处理,而不是由 Hibernate 处理。实体,顺便说一句,不共享。每个 Hibernate 会话都有自己的给定实体副本,其中包含在事务中从数据库中读取的数据。

    了解什么是数据库事务和 ACID。无论您是否使用 Hibernate,都不会改变任何事情。

    【讨论】:

    • Hibernate 确实包含二级缓存,因此在提交实体时,这些实体存储在二级缓存中,而不是数据库中。我说的对吗?
    • 没有。实体始终保存在数据库中。它们也可能存储在二级缓存中,但缓存不会替换数据库。并且二级缓存默认是关闭的。您必须启用它,并选择使实体可缓存,以将其存储在二级缓存中。我的建议:不要乱用二级缓存,除非你已经测量过它是绝对必要的。特别是如果您不完全了解 Hibernate 和事务如何在没有此缓存的情况下工作。
    【解决方案2】:

    事务是 DB(和休眠)中的原子操作。数据库引擎保证用户不会得到半更新的实体(如果您配置了事务管理权限;))。

    如果您的应用依赖于数据完整性,您还应该实现某种实体锁定。对于大多数用例而言,乐观锁定就足够了。 (如果不熟悉,请尝试在谷歌上搜索该术语)。

    【讨论】:

      猜你喜欢
      • 2012-04-29
      • 1970-01-01
      • 2021-11-16
      • 1970-01-01
      • 1970-01-01
      • 2022-01-18
      • 2018-11-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多