我们正在重构遗留应用程序。旧代码在Controller方法中做了类似的事情:
我们在服务层之间放置了一个,所以上面的代码现在看起来像:
上述两种更新方法中的每一种都已标记为事务性(使用spring事务)。旧代码没有很好地处理事务 - 现在,我们希望用户操作(控制器方法)仅映射到单个事务。我们如何使用弹簧交易本身实现这一目标?
PS:
答案 0 :(得分:4)
我们可以将上面的两种服务方法合并到一个方法中,但是会欢迎一些不会妨碍重用的清洁情况。
恕我直言,如果您尝试将这两种服务方法作为一个“工作单元”执行,那么最干净的解决方案是在服务层中使用@Transactional
方法调用它们。
答案 1 :(得分:3)
如果您想继续使用@Transactional
注释,那么您肯定必须将您的调用包装在更广泛的注释方法中。所以,你要么定义业务服务,这可能会变得非常模板化/冗余,或者你使你的控制器的处理方法本身是事务性的(作为@Component
它是一个Spring管理的bean,所以你也可以在那里使用@Transactional
,或者您定义一个灵活的,通用的,基于回调的模板:
@Component
public class TxWorker {
@Transactional
public <T> T doInTx(Callable<T> callback) throws Exception {
return callback.call();
}
}
后者的缺点是,如果过度使用它可能会有点乱。
请注意,您可以组合OpenSessionInView模式和Spring管理的事务,因为Hibernate会话(或JPA entityManager)可能跨越多个tx(请参阅What is the difference between Transaction-scoped Persistence context and Extended Persistence context?)。但它的主要目标是在渲染视图时提供延迟加载,因此它并不是您正在寻找的。 p>