TLDR :这是因为只有应用程序中的服务层才具有识别数据库/业务事务范围所需的逻辑。设计上的控制器和持久层无法/不应该知道事务的范围。
可以
@Transactional构造控制器,但实际上,通常建议仅使服务层具有事务性(持久性层也不应具有事务性)。
这样做的原因不是技术可行性,而是关注点分离。控制器的职责是获取参数请求,然后调用一个或多个服务方法并将结果合并为响应,然后将其发送回客户端。
因此,控制器具有协调请求执行的功能,并将域数据转换为客户端可以使用的格式(例如DTO)。
业务逻辑驻留在服务层上,而持久层只是从数据库中来回检索/存储数据。
数据库事务的范围实际上是一个业务概念,而不仅仅是一个技术概念:在帐户转帐中,只有在其他帐户被贷记等情况下才可以借记一个帐户,因此只有包含业务逻辑的服务层才能真正知道银行帐户转帐交易的范围。
持久层无法知道它在进行什么事务,例如method
customerDao.saveAddress。它是否应该始终在自己的独立事务中运行?没有办法知道,这取决于调用它的业务逻辑。有时它应该在单独的事务上运行,有时仅在它们
saveCustomer也起作用时才保存其数据,等等。
控制器也是如此:应该
saveCustomer和应该
saveErrorMessages进行同一笔交易吗?您可能想要保存客户,如果失败,则尝试保存一些错误消息并向客户端返回正确的错误消息,而不是回滚包括要保存在数据库中的所有错误消息在内的所有内容。
在非事务控制器中,由于会话已关闭,因此从服务层返回的方法将返回分离的实体。这是正常的,解决方案是使用
OpenSessionInView或执行渴望获取控制器知道所需结果的查询。
话虽如此,让控制员具有交易性不是犯罪,这不是最常用的做法。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)