0

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

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 读取 HibernateSharedEntity,其中 id=1
时间 4:User1 正在修改所有字段:例如 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 不能进行一次插入来更新这两个共享实体。因此,当 User1 在一个事务中更新更多共享实体时,是否有可能 User2 可以在“未同步状态”中读取这些实体,我的意思是当一个实体更新但另一个实体尚未更新时?

我认为它可能很复杂,所以我将尝试更多地解释它:在我的应用程序中,共享实体必须同步。例如,有两个共享实体,例如:
entity1 = {a=1,b=2,c=3,d=4}
entity2 = {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 会解决这个问题吗?先感谢您。

4

2 回答 2

1

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

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

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

于 2013-03-03T17:49:59.690 回答
0

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

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

于 2013-03-03T17:50:58.990 回答