【问题标题】:Hibernate: cleaning up sessionsHibernate:清理会话
【发布时间】:2015-03-13 08:54:36
【问题描述】:

假设我有以下内容:

public class DAOFactory {
    @Inject private final SessionFactory factory;
    private final ThreadLocal<Session> session = new ThreadLocal<>();

    // In a nutshell: create an AbstractDAO associated with the session object held by the ThreadLocal above
    public <T> AbstractDAO<T> createObject(Class<T> objectClass) { ... }
}

我遇到的问题是这些会话需要关闭,只有从createObject() 创建 DAO 的线程才能做到这一点。显然,AbstractDAO 不能有一个关闭例程,因为同一个Session 可以与多个AbstractDAO 对象相关联,所以DAOFactory 必须承担关闭会话的负担。尽管如此,Sessions 仍然存在悬空的风险:如果创建 AbstractDAO 的线程不再存在,如何关闭关联的 Session

我有一个方法是有一个清理方法如下:

public class DAOFactory {
    // createObject() uses Thread.getCurrentThread.getId() and sessionMap.computeIfAbsent()
    private final ConcurrentMap<Long, Session> sessionMap = new ConcurrentHashMap<>();

    public void cleanup() {
        for (Session session : sessionMap.values()) {
            session.close();
        }
        sessionMap.clear();
    }
}

问题是“这种方法有多安全”、“这是个好主意”和“应该这样做”吗?如果没有,有什么好的选择?

请注意,DAOFactory 的创建主要考虑了某种测试情况:一个线程开始测试运行并创建一个DAOFactory,它可能会产生使用它的其他线程。创建DAOFactory 的线程将始终比它产生的任何线程更持久,并且始终是在测试结束时调用cleanup() 的线程。

【问题讨论】:

    标签: java multithreading hibernate session thread-safety


    【解决方案1】:

    手动会话管理不是一个好主意。 Hibernate 已经提供了一个 SPI,所以你不必自己做。

    我建议你开始使用 Spring 事务管理,它也提供自动会话管理。

    【讨论】:

      猜你喜欢
      • 2015-07-05
      • 1970-01-01
      • 2011-09-19
      • 2020-07-07
      • 1970-01-01
      • 2013-01-10
      • 2012-04-19
      • 2010-10-13
      • 2013-03-14
      相关资源
      最近更新 更多