【发布时间】:2013-09-01 03:06:34
【问题描述】:
我在 stack-overflow 文章中看到了很多 cmets 我发现了一些关于 @Transactional 与 @Service 或 @Controller 一起使用的事情
“通常情况下,应该将事务放在服务层。”
“正常情况是在服务层级别进行注释”
“认为事务属于服务层。它了解工作单元和用例。如果您将多个 DAO 注入到需要在单个事务中协同工作的服务中,这是正确的答案。” [Source]
将@transactional 与@service 层一起使用的缺点
如果我有 2 种方法,例如 saveUser() 和 saveEmail()(因为我将电子邮件存储在数据库中以便稍后发送它们 - 就像一个队列)我会在我的服务中创建一个方法 saveUserAndSendEmail(User user) 这将交易。 [Source]
这意味着我在服务层创建了许多方法,而不是一个保存通用方法,如下所示
public <T> long save(T entity) throws DataAccessException {
Session session = sessionFactory.getCurrentSession();
long getGenVal=(Long) session.save(entity);
return getGenVal;
}
根据上面的解决方案,这意味着我们有很多方法,如以下LOL..
public <T> long saveAccount(T entity)....
public <T> long saveWithAuditLog(T entity, K entity1)....
public <T> long saveWithAuditLogAndEntries(T entity, K entity, M entity)....
克服这种情况
我在@Controller 中使用@Transactional 并创建一个通用保存方法并使用这个简单的保存方法保存所有实体/模型。如果任何方法保存失败,则控制器中的所有事务都成功回滚。
确保@Transactional 应与@Controller 一起使用的其他情况
在@Controller 中:
pt.save(entity1);
pt.save(entity2);
int a = 2/0;
pt.save(entity3);
万一,@Transactional on Service,前 2 个实体成功保存,但第三个不是,它不会回滚所有事务
万一,@Controller 上的@Transactional 发生异常时所有事务回滚
为什么 stack-overflow 会问,“不要在你的控制器中做事务。把它们放在你的服务层类中。”? [source]
【问题讨论】:
-
我认为这种情况下最好的解决方案是在
controller和service之间创建另一个级别层。正如我所看到的,controller只处理调用并准备变量来处理它们并对其执行逻辑。service处理所有数据库内容。应该在controller和service之间的模型可以做一些逻辑。在您的示例中,执行少量保存操作是对 data 的逻辑操作。这意味着将它们放入model并在需要时使用transactional扭曲model -
您的
saveUser()和saveEmail()方法应该在DAO 层中。然后你让你在服务层事务中的saveUserAndSendEmail(User user)方法。
标签: hibernate spring-mvc service controller transactional