hibernate - 回滚是否终止 session ?

标签 hibernate session transactions

我在以下情况下收到以下异常:

java.lang.IllegalStateException: Session/EntityManager is closed

我正在创建一个事务,我在其中使用 session.save() 保存对象; 我还没有提交事务,但是我正在使用 flush 将数据发送到数据库。任何人都可以清除我的回滚概念吗?它是如何工作的?使用刷新而不提交。

任何人都可以在我的代码下面解释我,我刚刚开始学习 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 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 已被标记为回滚时,您可以调用 Transaction#rollback() 或执行相同操作的一些内部异常处理代码,那是无法撤消的。

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

因此,您获得的异常是为了防止用户实质上使用 Session 或 EntityManager,其中持久上下文状态可能由于事件事务已被标记为回滚而未定义。

关于hibernate - 回滚是否终止 session ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50543040/

相关文章:

java - Hibernate Criteria API - 过滤集合属性

mysql - 如何在Hibernate中映射Spring Security表

php - 在索引页面上设置 PHP session 以进行 XSRF 检查

nhibernate - 如何配置NHibernate Facilities?

oracle - 触发语句级原子性

c# - TransactionScope 的层次结构

java - hibernate 、Java 9 和 SystemException

java - 实现 hashCode 和延迟加载

session - 如何使用解析 session token 通过 graphql 发出请求

java - 防止 Jetty 中 session 的最后访问时间更新