从 Hibernate 获取后台线程的新会话

发布于 2024-08-22 23:57:29 字数 331 浏览 3 评论 0原文

我正在开发一个网络应用程序。通常在请求开始时(通过架构代码),会打开一个 Hibernate 会话来处理数据库事务。请求结束时,会话关闭。这对于我们所有的事务都很有效,除了在一个特定的实例中,我想从请求中触发一个线程。该线程将调用数据库事务。

从线程中,我调用“sessionFactory.openSession()”,并通过此会话执行我的事务。问题的出现是当请求完成时,线程本身可能不一定完成。因此,当请求完成并且线程尝试执行另一个数据库事务时,我得到一个 Hibernate Session is Closed!错误。

无论如何,从我的线程中,我可以打开一个“干净”的会话,而不是与请求开始时打开的会话关联吗?

I'm working on a web application. Usually at the beginning of a request (through the architecture code), a Hibernate session is opened to work with DB transactions. At the end of the request the session is closed. This works great for all of our transactions, except that in one particular instance, I want to fire a thread from a request. This thread will call DB transactions.

From the thread, I call "sessionFactory.openSession()", and with this session I perform my transactions. The problem arises in that when the request finishes, the thread itself may not necessarily be finished. So when the request finishes and the thread tries to perform another DB transaction I get a Hibernate Session is Closed! error.

Is there anyway that from my thread, I can open a "clean" session, not associated to the one opened at the start of the request?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

您可以创建一个线程服务,它扩展了 HibernateAccessor,作为一个独立的 Spring 服务,在 spring.xml 中定义,并向其发送您想要处理的代码/数据。像这样的东西:

    Session session = SessionFactoryUtils.getSession(
            getSessionFactory(), getEntityInterceptor(), getJdbcExceptionTranslator());
    SessionHolder sessionHolder = null;
    try {
        applyFlushMode(session, false);
        sessionHolder = new SessionHolder(session);
        TransactionSynchronizationManager.bindResource(getSessionFactory(), sessionHolder);
        Transaction t = getSessionFactory().getCurrentSession().beginTransaction();
        try {

            //execute your code here

            t.commit();
        } catch (Exception e) {
            t.rollback();
            log.error("Error", e);
        }
        try {
            flushIfNecessary(sessionHolder.getSession(), false);
        }
        catch (HibernateException ex) {
            throw convertHibernateAccessException(ex);
        }
    } finally {
        SessionFactoryUtils.closeSession(sessionHolder.getSession());
        TransactionSynchronizationManager.unbindResource(getSessionFactory());
    }

You can create an threading service, which extends HibernateAccessor, as a standalone Spring service, defined at spring.xml, and send to it code/data you want to process. Something like this:

    Session session = SessionFactoryUtils.getSession(
            getSessionFactory(), getEntityInterceptor(), getJdbcExceptionTranslator());
    SessionHolder sessionHolder = null;
    try {
        applyFlushMode(session, false);
        sessionHolder = new SessionHolder(session);
        TransactionSynchronizationManager.bindResource(getSessionFactory(), sessionHolder);
        Transaction t = getSessionFactory().getCurrentSession().beginTransaction();
        try {

            //execute your code here

            t.commit();
        } catch (Exception e) {
            t.rollback();
            log.error("Error", e);
        }
        try {
            flushIfNecessary(sessionHolder.getSession(), false);
        }
        catch (HibernateException ex) {
            throw convertHibernateAccessException(ex);
        }
    } finally {
        SessionFactoryUtils.closeSession(sessionHolder.getSession());
        TransactionSynchronizationManager.unbindResource(getSessionFactory());
    }
我三岁 2024-08-29 23:57:29

您可以使用 JPA Entity Manager 手动开始和提交事务。 这是我的扩展答案

You can use JPA Entity Manager to begin and commit transactions manually. Here is my extended answer

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文