Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Hibernate 回滚是否终止会话?_Hibernate_Session_Transactions - Fatal编程技术网

Hibernate 回滚是否终止会话?

Hibernate 回滚是否终止会话?,hibernate,session,transactions,Hibernate,Session,Transactions,对于以下场景,我得到以下异常: java.lang.IllegalStateException: Session/EntityManager is closed 我正在创建一个使用session.save()保存对象的事务; 我还没有提交事务,但我正在使用flush将数据发送到数据库。有人能澄清我的回滚概念吗?它是如何工作的?使用flush和notcommit 谁能在下面解释一下我的代码,我刚刚开始学习hibernate Transaction tr1 = session.beginTrans

对于以下场景,我得到以下异常:

java.lang.IllegalStateException: Session/EntityManager is closed
我正在创建一个使用session.save()保存对象的事务; 我还没有提交事务,但我正在使用flush将数据发送到数据库。有人能澄清我的回滚概念吗?它是如何工作的?使用flush和notcommit

谁能在下面解释一下我的代码,我刚刚开始学习hibernate

Transaction tr1 = session.beginTransaction();
     session.save(c1);
     session.save(c2);
     c3.setCustName("Robby");
     session.save(c3);
     session.flush();
     tr1.rollback();

     session.save(c4);//Here its throwing above mentioned exception.
     session.save(c5);
     tr1.commit();  

提前谢谢

在您的用例中,您试图完成的似乎是在同一个会话中执行两个事务。最简单的方法就是这样

Session session = // you acquire a session from somewhere
try {
  // First trx
  session.getTransaction().begin();
  session.save( c1 );
  session.save( c2 );
  c3.setCustName( "Robby" ); 
  session.save( c3 );
  // at this point nothing has been sent to the database
  // if you want to send it to the db and start a new trx
  // you don't need to use flush, just commit it.
  session.getTransaction().commit();

  // Start a new trx
  session.getTransaction().begin();
  session.save( c4 );
  session.save( c5 );
  session.getTransaction().commit();
}
catch ( Exception e ) {
  if ( session.getTransaction().isActive() ) {
    session.getTransaction().rollback();
  }
  throw e;
}
finally {
  if ( session != null && session.isOpen() ) {
    session.close();
  }
}
这方面的主要问题是,第一个事务可能会成功,但没有问题,而第二个事务会失败,这取决于您的用例,这可能意味着当您希望提交所有事务或什么都不提交时,数据库状态不一致

更好的实施方式是:

Session session = // you acquire a session from somewhere
try {
  // First trx
  session.getTransaction().begin();
  session.save( c1 );
  session.save( c2 );
  c3.setCustName( "Robby" ); 
  session.save( c3 );

  session.save( c4 );
  session.save( c5 );
  session.getTransaction().commit();
}
catch ( Exception e ) {
  if ( session.getTransaction().isActive() ) {
    session.getTransaction().rollback();
  }
  throw e;
}
finally {
  if ( session != null && session.isOpen() ) {
    session.close();
  }
}
话虽如此,请理解当通过调用
Transaction#rollback()
或某些内部异常处理代码将
事务标记为回滚时,无法撤消该操作

此外,它通常意味着会话缓存中的状态对于所有意图和目的都是未定义的。如果查看大多数回滚处理的示例,您通常会发现唯一的选择是关闭该会话并尝试从全新的会话开始,而不仅仅是事务


因此,您得到的例外情况是,在持久性上下文状态可能未定义的情况下,禁止用户使用会话或EntityManager,因为活动事务已标记为回滚。

要检查transaction.rollback()对会话和事务本身做了什么,我编写了以下代码并进行了测试

       SessionFactory sf = cf.configure().buildSessionFactory();
       Session session = sf.openSession();

       Transaction tr = ss.beginTransaction();

        System.out.println( "******** before rollback ************");
        System.out.println("is TR active "+tr.isActive());      
        System.out.println("joind with TR "+session.isJoinedToTransaction());
        System.out.println("is open "+session.isOpen());
        System.out.println("is connected "+session.isConnected());

        tr.rollback();

        System.out.println( "******** After rollback ************");
        System.out.println(" is TR active "+tr.isActive());
        System.out.println("joind with TR "+session.isJoinedToTransaction());
        System.out.println("is open "+session.isOpen());
        System.out.println("is connected "+session.isConnected());
在输出中,我得到了这个

********回滚前**************
TR是否处于活动状态
true

与TR
true

是否打开
true

是否已连接
true

********回滚后************

TR是否处于活动状态
false

与TR连接
false

是否打开
true

是否已连接
true

从这个输出可以明显看出,在调用tr.rollback()之后

1.您先前启动的事务不再处于活动状态。
2.会话与事务分离。
3.会议仍然开放。
4.会话仍保持连接

因此,您仍然可以使用此会话再次启动新事务,它应该可以正常工作。
希望这能回答您关于tr.rollback()的所有问题。

无论是谁否决了这个答案,请说明我是否在某个地方犯了错误?这对我和其他人都有帮助。