不承诺Hibernate选择交易的一致性

时间:2016-08-18 21:25:25

标签: java hibernate transactions

我是Hibernate的新手,并继承了使用它的代码库。未定义自动提交,因此默认为false。根据我提出的其他问题,答案表明最佳做法是划分代码,这样如果你开始一个事务,你应该总是commit()或rollback()(感谢Apostolos)。 此代码库使用以下代码中的Select语句格式。我打算正确地将任何新代码划分为commit()或rollback(),但我很好奇使用下面的模型会产生什么后果。应用程序已经并将继续正常工作,但我想了解是否有现有代码的任何问题。

this.session = HibernateUtil.getSessionFactory().getCurrentSession();    
Transaction tx = session.beginTransaction();
session.clear();
entityReturned = (MultipleKeyTable) session.get(MultipleKeyTable.class, entityId);
session.close();

2 个答案:

答案 0 :(得分:1)

Session.close()"通过释放JDBC连接并清理"来结束会话。 (Hibernate SharedSessionContract docs)。这并不像我想的那样明确,但我能想到的每一个似是而非的解释都是“释放JDBC连接"意味着以这种或那种方式结束任何未结交易。然而,只是关闭会话而不是明确地结束交易最多是马虎。

为了它的价值,the Session docs推荐这个成语:

Session sess = factory.openSession();
Transaction tx = null;
try {
    tx = sess.beginTransaction();
    //do some work
    ...
    tx.commit();
}
catch (Exception e) {
    if (tx!=null) tx.rollback();
    throw e;
}
finally {
    sess.close();
}

如果需要,您可以在关闭之前在同一会话中运行多个事务。

答案 1 :(得分:0)

我建议有几项改进:

  1. SessionFactory 而非会话存储为您的类成员:因为您在完成工作后关闭了会话对象,因此无法重复使用此实例,因此你需要新的,可以从 SessionFactory ;

  2. 中重新获得
  3. 不要调用 clear()方法:因为您正在使用当前会话对象调用 clear()可能会删除所有持久化上下文中但没有的对象但是在数据库中刷新了,所以你可能会丢失数据;

  4. 完成工作后提交或回滚交易。

  5. 所以代码必须是:

         this.sessionFactory = HibernateUtil.getSessionFactory();
         Session session = this.sessionFactory.getCurrentSession();    
         Transaction tx = session.beginTransaction();
    
         entityReturned = (MultipleKeyTable) session.get(MultipleKeyTable.class, enti
    
         transaction.commit();
         session.close();