【发布时间】:2017-04-24 22:33:23
【问题描述】:
我的问题是 JPA/Hibernate 为 entityManager.getTransaction().isActive() 的调用返回 true,即使我没有明确启动事务(参见代码如下)。
这里的问题是我想从数据库中读取一些东西,并且在这种情况下 SerializationException 是可以的,因为这只是表明持久化对象不再适合实际代码,需要重新计算。下面的代码不仅返回 null,还引发了以下异常:
Transaction rollback failed.
org.hibernate.TransactionException: Unable to rollback against JDBC Connection
这告诉我,我的代码中一定有一个事务不是我开始的。上面代码中的 finally 块是
final EntityManager entityManager = Persistence.createEntityManagerFactory("test").createEntityManager();
try {
final TypedQuery<Test> query = entityManager.createQuery("SELECT t FROM test t", Test.class);
return query.getResultList();
} catch (final PersistenceException e) {
if (e.getCause() instanceof SerializationException) {
LOG.debug("Implementation changed meanwhile. That's ok - we return null.");
return null;
}
throw e;
} finally {
EntityManagerCloser.closeEntityManager(entityManager);
}
EntityManagerCloser 看起来像这样:
public final class EntityManagerCloser {
private static final Logger LOG = LoggerFactory.getLogger(EntityManagerCloser.class);
public static void closeEntityManager(EntityManager entityManager) {
if (entityManager.getTransaction().isActive()) {
try {
entityManager.getTransaction().rollback();
} catch (PersistenceException | IllegalStateException e) {
LOG.error("Transaction rollback failed.", e);
}
}
if (entityManager.isOpen()) {
try {
entityManager.close();
} catch (IllegalStateException e) {
LOG.error("Closing entity manager failed.", e);
}
}
}
}
Hibernate docs 表示“始终使用清晰的事务边界,即使对于只读操作也是如此”。所以我真的需要插入一个
entityManager.getTransaction().begin();
....
<do read here>
....
entityManager.getTransaction().commit();
围绕我对数据库执行的每个读取操作?
我可以在没有回滚事务块的情况下为只读操作实现另一个 closeEntityManager 方法,但我想了解为什么存在事务。感谢您的帮助!
【问题讨论】:
标签: java hibernate jpa transactions