在多线程环境中创建hibernate会话时,最佳做法是什么?

时间:2015-04-08 19:17:55

标签: java multithreading hibernate session

目前,对于我的项目,我正在为每个与数据库相关的查询创建会话并立即关闭它。

public Address address(Contact contact) {
    Address result = null;
    Session session=factory.openSession();
    try{
        result = contact.getAddress();
    } finally {
        session.close();
    }
    return result;
}

在网页的单个执行线程中,在java代码和JSP代码中有许多类似于上面的调用。

另外,我在自己的执行调用的线程中有一个java任务,需要打开一个会话并在同一个线程中关闭它。

出于某种原因,偶尔我会得到一个会话超时,只有一个用户登录我的应用程序,10个线程在后台运行。

问题是......我应该在执行整个页面之前在过滤器中创建一个会话,并在所有与数据库相关的方法中调用factory.getCurrentSession()吗?如果在过滤器中处理请求后关闭过滤器中的会话,这是否是线程安全的?这种方法是否会使应用程序可扩展并防止会话超时?

1 个答案:

答案 0 :(得分:0)

我不能保证它会解决您的会话超时,因为您实际上没有根本原因(我会触发超时,然后执行线程转储以进一步调试)。

但是,我在几个项目的过滤器中管理了会话,取得了巨大的成功和性能。这是一种称为session-per-request的常见方法。我自己没有使用factory.getCurrentSession()因为我使用JPA而只是创建了一个ThreadLocal来存储EntityManager(例如会话),所以我自己设置了它。上面的链接引用了factory.getCurrentSession(),因此只要您正确使用它,它就可以正常工作。

如果您需要进一步提高性能,可以在过滤器中设置一些机制来确定您的请求是否需要访问数据库(如果您的所有请求都访问数据库,这将是毫无意义的)并且如果它们不需要访问数据库不创建会话。但是,如果我记得,当您第一次使用会话时会非常有效地初始化会话,因此创建未使用的会话所带来的性能应该非常小。