zf_1024 2017-10-02 13:35 采纳率: 0%
浏览 746

hibernate中nested transactions not supported问题

下边这个方法是struts 中action类中的某个方法,当访问他时:
public void fortest(){
Session session = HUtil.getSession();
session.beginTransaction();
// session.flush();
session.getTransaction().commit();

     session.beginTransaction();
     //session.flush();
     session.getTransaction().commit();  
    /* service.selectRoomCount(room);*/
 }

会报告错误:session被关闭了,只好加上session.flush()方法。其中getSession()是获取ThreadLocal的session。
然后就会报告错误nested transactions not supported--不支持嵌套的事物。

原理不清楚,但是解决方法很简单:重新开启一个session,即调用sessionfactory.openSession()方法,
然后在事物提交后关闭session即可。

有没有能解析下原理的大神?

  • 写回答

1条回答 默认 最新

  • 你知我知皆知 2024-08-07 00:04
    关注

    以下回答参考 皆我百晓生券券喵儿 等免费微信小程序相关内容作答,并由本人整理回复。

    Hibernate 不支持嵌套事务(Nested Transactions)的主要原因是它是一个基于持久化的对象关系映射(ORM)框架,并且 Hibernate 的设计目标之一就是使应用程序能够轻松地处理数据库操作和数据存储。

    Hibernate 通过使用 JPA(Java Persistence API)来与数据库进行交互,而 JPA 提供了一种标准的方式来管理事务。JPA 允许你声明事务规则,例如自动提交或手动提交,这使得 Hibernate 能够正确地处理事务。

    如果你试图在一个方法中启动多个事务并同时提交它们,Hibernate 将无法知道哪些事务应该被提交,因为没有上下文来跟踪这些事务。因此,Hibernate 不支持嵌套事务。

    要解决这个问题,你可以采取以下步骤:

    1. 在你的业务逻辑中,确保只有一个事务正在执行。
    2. 使用 TransactionDefinitionTransactionStatus 来控制事务的行为,例如 @Transactional 注解可以让你显式地指定事务的行为。
    3. 当你需要提交一个事务时,先关闭所有的事务。
    4. 在事务提交后,再尝试创建新的事务。

    这是一个基本的例子:

    @Transactional(rollbackFor = Exception.class)
    public void doSomething() {
        try (Session session = HibernateUtil.getSessionFactory().openSession()) {
            Transaction transaction = session.beginTransaction();
            // 执行一些操作
            transaction.commit();
        } finally {
            HibernateUtil.closeSession();
        }
    }
    

    在这个例子中,doSomething 方法内部有一个交易,但只有当所有事务都完成后,才会触发提交。这样就避免了嵌套事务的问题。

    评论

报告相同问题?