休眠:同时进行两个或多个事务:事务已处于活动状态 [英] Hibernate: Two or more transactions at the same time: Transaction already active

查看:103
本文介绍了休眠:同时进行两个或多个事务:事务已处于活动状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个REST API,当我几乎同时进行POST和GET时,会遇到此异常:

I have a REST API and when i make a POST and a GET nearly the same time i get this exception:

 SEVERE: The RuntimeException could not be mapped to a response, re-throwing to the HTTP container
java.lang.IllegalStateException: Transaction already active
    at org.hibernate.engine.transaction.internal.TransactionImpl.begin(TransactionImpl.java:52)
    at org.hibernate.internal.AbstractSharedSessionContract.beginTransaction(AbstractSharedSessionContract.java:409)
    at sun.reflect.GeneratedMethodAccessor89.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.hibernate.context.internal.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:355)
    at com.sun.proxy.$Proxy58.beginTransaction(Unknown Source)
    at utils.HibernateSession.createTransaction(HibernateSession.java:15)
    at api.ConversationsREST.getMessages(ConversationsREST.java:128)

它们在不同的类上,因此没有暗示全局属性.

They are on different classes so no global attributes implied.

失败的行是这个:

HibernateSession hs = new HibernateSession();
hs.createTransaction(); // Crash

这是指我的课程HibernateSession:

Wich refers to my class HibernateSession:

public class HibernateSession {

    public Session session;

    public void createTransaction() {

        session = HibernateUtil.getSessionFactory().getCurrentSession(); //THIS WAS WRONG
 //EDIT:session = HibernateUtil.getSessionFactory().openSession(); //THIS IS RIGHT
        session.beginTransaction();
    }

    public void commitclose() {

        session.getTransaction().commit();
        session.close();

    }

    public void rollbackclose() {

        try {
            session.getTransaction().rollback();
            session.close();
        } catch (Exception hibernateexception) {
            hibernateexception.printStackTrace();
        }

    }

}

该异常实际上是在session.beginTransaction()

我总是创建一个hs.commitclose(),在catch()块和404中,我总是创建一个rollbackclose();

I always make a hs.commitclose() and in the catch() blocks and the 404s I always make a rollbackclose();

问题是当我发出这样的POST消息时:

The problem is that when I make a POST messages like this:

HibernateSession hs = new HibernateSession();
hs.createTransaction();
hs.session.save(whatever);
hs.commitclose();

返回200,就可以了,但是GET可能会崩溃,但上面的异常除外. 在创建HibernateSession的 new 实例时,为什么Hibernate似乎试图共享该交易?

Returns 200 and it's ok but then the GET may crash with the exception above. As I am makeing a new instance of HibernateSession, why Hibernate seems to be trying to share that transaction?

仅当我在很短的时间内进行两个查询时才会发生这种情况(我猜想在另一个人的开始和提交之间开始一个事务).所以我猜Hibernate认为会话属性是静态的或类似的东西...

This only happens when I make both querys in a very short time (i guess starting a transaction between the beginning and the commit of anotherone). So i guess Hibernate is thinking that session attribute is static or something like that...

:根据要求,HibernateUtil.java(问题一定不在这里,但可能有助于理解):

As requested, HibernateUtil.java (the problem must not be here but may help to understand):

package utils;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtil {

    private static SessionFactory sessionFactory;

    public static SessionFactory getSessionFactory() {

        if (sessionFactory == null) {

            sessionFactory = build();

        }
        return sessionFactory;

    }

    private static SessionFactory build() {

        try {

            return new Configuration().configure().buildSessionFactory();

        } catch (Throwable ex) {

            System.err.println("Initial SessionFactory creation failed: " + ex);
            throw new ExceptionInInitializerError(ex);
        }

    }

}

推荐答案

根据您的createTransaction逻辑,您正在从SessionFactory获取当前会话并从中开始事务.

As per your createTransaction logic, you are getting current session from SessionFactory and starting a transaction from it.

这是问题所在.

让我们假设您已经创建了HibernateSession对象并开始了事务,但是该事务仍在进行中.因此,您尚未关闭交易.

Lets assume you have created HibernateSession object and started transaction but it is still in progress. So you haven't close transaction yet.

现在您创建了另一个HibernateSession并尝试启动事务,这样做将引发异常.

Now you created another HibernateSession and try to start transaction, doing this will throw exception.

所以您的这段代码

public void createTransaction() {
    session = HibernateUtil.getSessionFactory().getCurrentSession();
    session.beginTransaction();
}

必须是

public void createTransaction() {
    session = HibernateUtil.getSessionFactory().openSession();
    session.beginTransaction();
}

getSessionFactory().openSession()总是会打开一个新会话,您必须在完成操作后关闭该会话.

getSessionFactory().openSession() always opens a new session that you have to close once you are done with the operations.

getSessionFactory().getCurrentSession()返回绑定到上下文的会话-您无需关闭该会话.

getSessionFactory().getCurrentSession() returns a session bound to a context - you don't need to close this.

这篇关于休眠:同时进行两个或多个事务:事务已处于活动状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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