休眠:同时进行两个或更多事务:事务已处于活动状态

问题描述 投票:4回答:5

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

 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)

它们在不同的类上,所以没有暗示全局属性。

失败的行是此行:

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

这是指我的课程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();

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

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

返回200,就可以了,但是GET可能会崩溃,但以上情况除外。当我创建HibernateSession的new实例时,为什么Hibernate似乎试图共享该事务?

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

谢谢您的帮助!

编辑:根据要求,HibernateUtil.java(问题一定不在这里,但可以帮助您理解):

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);
        }

    }

}

我有一个REST API,当我几乎同时进行POST和GET时,收到此异常:SEVERE:无法将RuntimeException映射到响应,重新抛出到HTTP容器java。...] >

java hibernate rest jersey
5个回答
3
投票

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

这里是问题。


1
投票

您有一些与设计有关的缺陷:


1
投票
实际上,您的实际代码中有很多缺点:

    您每次调用代码时都在创建HibernateSession类的新实例,因此您将拥有许多实例,试图访问同一会话。

0
投票
我刚刚改变了

session = HibernateUtil.getSessionFactory().getCurrentSession();


-1
投票
尝试将代码重写为

public class HibernateSession { public Session session; int id; Transaction t = null; public void createTransaction() { session = HibernateUtil.getSessionFactory().getCurrentSession(); t = session.beginTransaction(); } public void commitclose() { t.commit(); session.close(); } public void rollbackclose() { try { t.rollback(); session.close(); } catch (Exception hibernateexception) { hibernateexception.printStackTrace(); } } }

© www.soinside.com 2019 - 2024. All rights reserved.