Hibernate线程安全集合 [英] Hibernate thread-safe collections

查看:46
本文介绍了Hibernate线程安全集合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是休眠会话线程安全性的延续.所有详细信息也适用于此.简而言之,执行遵循以下模式:

This is somewhat of a continuation of Hibernate session thread safety. All of the details apply here as well. In simplified terms, execution follows the pattern of:

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

所有实体均已配置为可以立即加载,并且在2期间根本无法访问会话.

The entities are all configured for eager loading, and the session is not accessed at all during 2.

2 中涉及的工作需要对持久性集合进行很少的修改.这就是我现在拥有的:

The work involved in 2 requires infrequent modification of a persistent collection. This is what I have now:

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

这工作得很好,但是我正在尝试防白痴"这个系统,并且我正在寻找一种方法来将并发控制尽可能地移到持久层.我已经在dao中尝试过此方法:

This works just fine, but I'm trying to "idiot-proof" this system and I'm looking for a way to move the concurrency control as far down into the persistence layer as I can. I've tried this in the dao:

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

哪个会导致 org.hibernate.HibernateException:具有实体="all-delete-orphan"的集合不再被拥有的实体实例引用...

有人有没有将线程安全引入休眠集合的方法,还是某种其他不需要污染业务逻辑的干净方法来控制并发访问和修改?

Does anybody have a way to introduce thread-safety to hibernate collections, or some other clean way to control concurrent access and modification in a way that doesn't require polluting the business logic?

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

Update- Here is what I ended up doing, per Pace's suggestion:

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

工作完成后,我保存了所有子项并调用 currentSession().merge(parent).就像魅力一样!

After the work is done, I save all of the children and call currentSession().merge(parent). Works like a charm!

推荐答案

  1. 阅读实体
  2. 分离实体
  3. 执行昂贵的,易于并行化的工作
  4. 合并实体
  5. 提交交易

如果第3步需要花费大量时间,那么我会建议:

If step 3 takes any significant amount of time then I would recommend simply:

  1. 打开会话(可以是只读的)
  2. 阅读实体
  3. 关闭会话
  4. 执行昂贵的,易于并行化的工作
  5. 打开一个新会话
  6. 合并实体
  7. 关闭会话

在分离/分离时,您应该能够将集合包装在线程安全的集合中.合并不应在乎您具有什么集合实现.但是我还没有测试.

While detached/unattached you should be able to wrap the collections in thread safe collections. The merge should not care what collection implementation you have. I have not tested it however.

这篇关于Hibernate线程安全集合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆