共享会话实体

时间:2013-03-01 20:40:56

标签: java hibernate web

假设我们有一个使用Hibernate的Web应用程序。 我的问题是发生了什么,如果来自不同用户的两个不同的转换,访问和操纵同一个实体?例如,我们有一个名为'Student'的实体,它有一个字段'age'。现在,来自不同用户的两个不同的事务使用Hibernate会话获取该实体,例如:

Student student = session.load(1); // 1 is the id of some student

然后一个用户操纵年龄字段,例如:     student.setAge(12); 第二个用户是否在完全另一个事务中看到了该更改? 我的意思是如果第二个用户在他自己的交易中调用     student.getAge() 他看到了新的价值吗 - 12? 请注意,更改age属性的第一个用户尚未提交该事务。

3 个答案:

答案 0 :(得分:1)

这只是一个休眠问题。其他用户是否看到未提交的数据取决于您是否已将数据库连接的隔离级别更改为read-uncommitted。没有太多有效的理由你想要这样做,并且除非被覆盖,否则hibernate将默认为read-committed。所以一般情况下,不会,其他用户在提交事务之前不会看到更改。

如果您降低了隔离级别,那么它将归结为SQL实际发送到数据库的时间。这是基于hibernate的刷新设置,在多层系统中可能有点难以预测。但基本上调用setAge不会将SQL发送到其他人可以看到的数据库。导致刷新的东西必须发生,这些东西再次依赖于配置。

进一步注意,如果第二个会话在提交更新之前加载实体,即使第一个会话提交更新,第二个会话也不会自动神奇地更新其内存中实体,除非您明确地在其上调用refresh。如,

Time 1: Session A loads Student 1
Time 2: Session B loads Student 1
Time 3: Session A sets new age and commits
Time 4: Session B gets Age, will still see old value
Time 5: Session B calls refresh on Student 1
Time 6: Session B gets Age, will see new value set in Session A

答案 1 :(得分:0)

请看这里:Hibernate session thread safety。我认为这与你的要求非常相似。基本上,在多个线程中使用会话并不是一个好主意。因此,假设您使用的是不同的会话,则第二个用户将看不到更改。

答案 2 :(得分:0)

在这种情况下,Hibernate擅长在多个线程中同时更新。

首先,在这种情况下不存在线程安全问题。因为每个事务都拥有自己的会话,所以每个会话将分别在其所谓的第一级缓存中保存其加载的对象。两个线程中的两个实例不会互相看到,

其次,当多个事务更新同一记录时,optimastic-locking机制将起作用。这是先到先得的模式。第一个提交的事务发生故障,第二个提交的事务将失败抛出异常。因为hibernate会在更新操作提交之前检查versin属性以查看版本是否是原始版本。

请参阅http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/transactions.html