Hibernate线程安全的集合

时间:2013-11-25 22:39:34

标签: java multithreading hibernate collections

这有点是Hibernate session thread safety的延续。所有细节也适用于此。简而言之,执行遵循以下模式:

1. Read entity
2. Do expensive, easily parallelizable work
3. Persist changes

实体都配置为预先加载,并且在2期间根本不访问会话。

2中涉及的工作需要不经常修改持久性集合。这就是我现在所拥有的:

synchronized (parentEntity) {
    parentEntity.getChildEntities().add(childEntity);
}

这很好用,但我正试图“防止”这个系统,我正在寻找一种方法将并发控制尽可能地延伸到持久层。我在dao中试过这个:

@Transactional
public ParentEntity getParentEntityById(long id) {
    ParentEntity parent = ...;
    parent.setChildren(Collections.synchronizedSet(parent.getChildren()));
    return parent;
}

导致org.hibernate.HibernateException: A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance...

是否有人有办法为hibernate集合引入线程安全性,或者以不需要污染业务逻辑的方式控制并发访问和修改的其他一些干净方法?

更新 - 根据Pace的建议,这就是我最终做的事情:

@Transactional
public ParentEntity getParentEntityById(long id) {
    ParentEntity parent = ...;
    currentSession().evict(parent);
    parent.setChildren(Collections.synchronizedSet(parent.getChildren()));
    return parent;
}

工作完成后,我保存所有孩子并致电currentSession().merge(parent)。像魅力一样工作!

1 个答案:

答案 0 :(得分:3)

  1. 阅读实体
  2. 分离实体
  3. 做昂贵,易于并行化的工作
  4. 合并实体
  5. 提交交易
  6. 如果第3步需要很长时间,那么我建议简单地说:

    1. 打开会话(可以是只读)
    2. 阅读实体(ies)
    3. 关闭会话
    4. 做昂贵,易于并行化的工作
    5. 开设新会话
    6. 合并实体(ies)
    7. 关闭会话
    8. 在分离/未连接时,应该能够将集合包装在线程安全集合中。合并不应该关心你有什么集合实现。我没有测试过它。