Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 休眠共享实体竞争条件_Java_Hibernate - Fatal编程技术网

Java 休眠共享实体竞争条件

Java 休眠共享实体竞争条件,java,hibernate,Java,Hibernate,我有一个问题,如果两个不同的web用户在同一个实体上工作,会发生什么。 例如,共享实体有四个字段: class HibernateSharedEntity { int id; int a; int b; int c; int d; } 现在,两个用户同时打开一个事务。其中一个正在更新此实体,第二个用户正在读取此实体。以下步骤将更好地解释这一点: 时间1:Hibernate实体存储在数据库中,其值为:a=b=c=d=0和id=1。 时间2:User1打开一个新事务。 时间3:User1读取Hib

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

class HibernateSharedEntity
{
int id;
int a;
int b;
int c;
int d;
}
现在,两个用户同时打开一个事务。其中一个正在更新此实体,第二个用户正在读取此实体。以下步骤将更好地解释这一点:

时间1:Hibernate实体存储在数据库中,其值为:a=b=c=d=0和id=1。
时间2:User1打开一个新事务。
时间3:User1读取HibernateShareIdentity,其中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状态(提交后)。我知道hibernate可以进行一次插入来更新所有这些值,但在我的应用程序中,它似乎更复杂,因为这个共享实体与其他共享实体有关系,也可以由User1更新。所以从现在起,hibernate不能进行一次插入来更新这两个共享实体。因此,当User1在一个事务中更新更多共享实体时,是否有可能User2可以在“非同步状态”下读取这些实体?我的意思是当一个实体被更新,但另一个实体尚未更新

我认为它可能很复杂,因此我将尝试更多地解释: 在我的应用程序中,必须同步共享实体。例如,有两个共享实体,如:
实体1={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}
实体2={a=5,b=6,c=7,d=8}
如您所见,entity1已更新,但entity2未更新。这是我申请的一个关键点,不可能出现这种情况。我怎样才能避免这种情况?hibernate负责这件事吗?
提前谢谢你。

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

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


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

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


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

Hibernate确实包含二级缓存,所以在提交实体时,这些实体存储在二级缓存中,而不是数据库中。我说的对吗?不对。实体总是保存在数据库中。它们也可能存储在二级缓存中,但缓存不会替换数据库。默认情况下,二级缓存处于禁用状态。您必须启用它,并选择使实体可缓存,才能将其存储在二级缓存中。我的建议是:不要弄乱二级缓存,除非您已经测量到它是绝对必要的。特别是如果您不完全理解没有这个缓存时Hibernate和事务是如何工作的。