我有一个代码保存一个bean,并通过Hibernate更新数据库中的另一个bean。它必须在同一个事务中执行,因为如果发生错误(f.ex启动一个Exception),必须为这两个操作执行回滚。如何做不失密封的交易?
public class BeanDao extends ManagedSession {
public Integer save(Bean bean) {
Session session = null;
try {
session = createNewSessionAndTransaction();
Integer idValoracio = (Integer) session.save(bean); // SAVE
doOtherAction(bean); // UPDATE
commitTransaction(session);
return idBean;
} catch (RuntimeException re) {
log.error("get failed", re);
if (session != null) {
rollbackTransaction(session);
}
throw re;
}
}
private void doOtherAction(Bean bean) {
Integer idOtherBean = bean.getIdOtherBean();
OtherBeanDao otherBeanDao = new OtherBeanDao();
OtherBean otherBean = otherBeanDao.findById(idOtherBean);
.
. (doing operations)
.
otherBeanDao.attachDirty(otherBean)
}
}
的问题是:
在情况下
session.save(bean)
启动一个错误,然后我得到AssertionFailure,因为函数doOtherAction(即在项目的其他部分使用)用途会抛出异常之后的会话。
我想的第一件事是提取功能doOtherAction的代码,但后来我有相同的代码复制,并没有似乎做它的最佳实践。
什么是重构这个最好的方法?
作为一个不得不维护大量使用共享会话/事务(反)模式的代码的人,我可以说在开发阶段使用它并不明智,只是为了避免一些配置工作和重构。这种解决方案往往会增加维护成本。在某种程度上,有人会忘记进行交易,会话会泄漏,您将遇到计划任务或应用程序集群问题等问题。从完全务实的角度来看,我并不是在谈论“理想”方法,只是“长期证明廉价”。 – 2011-05-05 14:36:20
只是为了修改我所说的话:共享会话/事务是一种解决方法,它可以快速复制和粘贴到任何地方,而早期或后期会成为项目中事务管理的某种标准。请不要创造一个怪物。 – 2011-05-05 14:56:10
@安东尼,当然,但这是事情。这种情况只需要实际的交易,这对于这种情况来说(显然)是非常罕见的。所以,DAO的正常机制仍然存在(当然,这仍然可能会泄漏)。然后,如果有人想稍后添加另一个多bean事务,他们可能会剪切并粘贴这个原始代码,从而保留该模式。当然,作为一个副作用。但是,他也没有提到他的代码是在服务器上,在客户端上还是在服务器上。做你认为他需要EJB或Spring或其他框架的东西。这对他来说可能不实际。 – 2011-05-05 23:07:38