【问题标题】:What is the best practice when it comes to creating hibernate sessions in multi-threaded environment在多线程环境中创建休眠会话的最佳实践是什么
【发布时间】:2015-06-13 22:21:14
【问题描述】:

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

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() 吗?如果我在过滤器中处理请求后关闭过滤器中的会话,这将是线程安全的吗?这种方法是否会使应用程序具有可扩展性并防止会话超时?

【问题讨论】:

    标签: java multithreading hibernate session


    【解决方案1】:

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

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

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

    【讨论】:

    • 谢谢.. 我放入的 sn-p 用于延迟加载关联对象,因为我在 *.hbm.xml 文件中声明它们是延迟的.. 这对你很有帮助.. . 我开始更改我的代码.. 希望我不会面临线程安全问题...
    • 我尝试在配置文件中添加 org.hibernate.context.internal.ThreadLocalSessionContext 并尝试使用 factory.getCurrectSession().. 但是当我尝试访问网页,服务器返回一个空白的 html 文件...有人知道为什么会这样吗?
    • 最后我让它工作了......添加了 线程 并使用了 factory.getCurrectSession()。没有添加任何其他内容..它按我的预期工作..谢谢..
    猜你喜欢
    • 1970-01-01
    • 2010-11-19
    • 2016-01-03
    • 2021-04-02
    • 1970-01-01
    • 2020-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多