找到对集合的共享引用:从同一用户会话并行使用事务时



我正在使用 hibernate 3.3 和 spring 3.0.5 并使用 JPA 事务管理器。我的场景是一个 ui 页面,在服务层上调用两个 get 方法来呈现 UI 中的两个区域,请求是并行的 ajax 请求。服务层中的 get 方法返回同一实体的两个"单独"列表。

List<Car> getCarsA();
List<Car> getCarsB();

我已经配置了JPA事务管理器,如下所示:

<tx:method name="get*" read-only="true" propagation="REQUIRED"/>

问题:当休眠/JPA 调用在每个服务方法结束后刷新时,可能存在一些集合(通过多对多映射),这些集合在方法返回的两个列表之间共享,因此会出现异常。我也在使用OpenEntityManagerInViewFilter。如果我串行调用方法,我不会遇到此错误。

休眠会话对象不是线程安全的。您必须为每个线程使用自己的会话实例,或者必须将对会话实例的访问与 java synchronized 块同步。

在 Web 环境中,每个浏览器会话应至少使用一个休眠会话。同一浏览器会话的访问可以是synchronized的,也可以使用多个会话(当您同时获取 UI 的不同区域时,我会将其与synchronized同步,除非一个查询需要相当长的时间,而其他查询不应该等待)。

注意: 一个会话中的更新在另一个会话中不直接可见(如果实例已缓存在另一个会话中)。