我想我是另一个不了解 Hibernate 会话的新手,可能是 Spring 的 TransactionTemplate,不知道。这是我的故事。
我正在使用 Hibernate 3.5.5-Final、Spring 3.0.4.RELEASE,试图只使用注释(对于 Hibernate 和 Spring MVC)。
我的第一次尝试是将@Transactional 注释与正确设置的事务管理器结合使用。起初似乎可以工作,但从长远来看(大约 36 小时),我开始一遍又一遍地收到“LazyInitializationExceptions”(来自前几个小时运行良好的地方!)。
所以我切换到使用 Spring TransactionTemplate 的手动事务。
基本上我的 BaseService 中有类似受保护的东西
@Autowired
protected HibernateTransactionManager transactionManager;
protected void inTransaction(final Runnable runnable) {
TransactionTemplate transaction = new TransactionTemplate(transactionManager);
transaction.execute(new TransactionCallback<Boolean>() {
@Override
public Boolean doInTransaction(TransactionStatus status) {
try {
runnable.run();
return true;
} catch (Exception e) {
status.setRollbackOnly();
log.error("Exception in transaction.", e));
throw new RuntimeException("Exception in transaction.", e);
}
}
});
}
并且使用服务的 impls 中的这种方法工作正常,我没有看到 LazyInitializationException 10 天(使用这个单一应用程序 24*7 运行 Tomcat 10 天,没有重新启动)......但是比箍!它再次弹出:-/
LazyInitializationException 来自“inTransaction”方法下的位置,并且不涉及“inTransaction 递归”,所以我很确定我应该在同一个 Hibernate 会话中处于同一个事务中。不涉及“来自先前会话的数据”(就我的代码而言,服务层打开事务,从 Hibernate 收集它需要的所有数据,处理它并返回一些结果 == 服务不调用其他顶级服务)
我还没有分析我的应用程序(我什至不知道如何在 10 天之类的长期运行中正确地做到这一点),但我唯一的猜测是我在某处泄漏内存并且 JVM 达到堆限制......有吗Spring 或 Hibernat 中涉及一些“SoftReferences”?我不知道...
另一个有趣的事情是,当我尝试使用 Google GSON 序列化程序将结果序列化为 JSON 时,总是会发生异常。我知道,它不使用 getter ...我有自己的补丁版本,它使用 getter 而不是实际字段(所以我确保不绕过 Hibernate 代理机制),你认为它可能在这里起到一些作用吗?
最后一个有趣的事情是,异常总是发生在单一服务方法中(而不是其他任何地方),这让我发疯了,因为这种方法尽可能简单愚蠢(没有极端的数据库操作,只是加载数据并序列化它们使用延迟获取到 JSON),嗯???
有没有人有任何建议我应该尝试什么?你有类似的经历吗?
谢谢, 雅库布