为什么将@Transactional 与@Service 一起使用而不是与@Controller 一起使用 [英] Why use @Transactional with @Service instead of with @Controller

查看:39
本文介绍了为什么将@Transactional 与@Service 一起使用而不是与@Controller 一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 stack-overflow 文章中看到了很多评论,我发现了一些关于 @Transactional@Service@Controller 一起使用的事情

I have seen many comments in stack-overflow articles I found certain things about either @Transactional use with @Service or with @Controller

通常,应该将事务放在服务层."

"Usually, one should put a transaction at the service layer."

正常情况是在服务层级别进行注释"

"The normal case would be to annotate on a service layer level"

"认为事务属于服务层.它是了解工作单元和用例的人.如果您将多个 DAO 注入到需要在单个事务中协同工作的服务中,这是正确的答案."[来源]

"Think transactions belong on the Service layer. It's the one that knows about units of work and use cases. It's the right answer if you have several DAOs injected into a Service that need to work together in a single transaction." [Source]

将@transactional 与@service 层一起使用的缺点

如果我有 2 个方法,例如 saveUser() 和 saveEmail()(因为我将电子邮件存储在数据库中以便稍后发送 - 就像一个队列)我会在我的服务中创建一个方法 saveUserAndSendEmail(User user)是交易性的.[来源]

If I had 2 methods for example saveUser() and saveEmail() (because I store the emails in a database to send them later - like a queue) I would create in my service a method saveUserAndSendEmail(User user) which would be transactional. [Source]

这意味着我在服务层创建了许多方法而不是一个保存通用方法,如下所示

public <T> long save(T entity) throws DataAccessException {
    Session session = sessionFactory.getCurrentSession();
    long getGenVal=(Long) session.save(entity);
    return getGenVal;
}

根据上面的解决方案,这意味着我们有很多方法,比如像LOL..

public long saveAccount(T entity)....

public long saveWithAuditLog(T entity, K entity1)....

public long saveWithAuditLogAndEntries(T entity, K entity, M entity)....

克服这种情况

我在@Controller 中使用@Transactional 并创建一个通用保存方法并使用这个简单的保存方法保存所有实体/模型.如果任何方法保存失败,则控制器回滚所有事务成功.

I USE THE @Transactional in @Controller and Just make a Generic Save Method and save all the entities/ model using this simple save method. and if any method fail to save then all the transactions in controller rollback successfully.

确保@Transactional 应该与@Controller 一起使用的其他情况

在@Controller 中:

In @Controller:

pt.save(entity1);
pt.save(entity2);
int a = 2/0;
pt.save(entity3);

如果@Transactional on Service,前2个实体成功保存,但第三个不是,它不会回滚所有事务

万一,@Controller 上的@Transactional 发生异常时所有事务回滚

为什么堆栈溢出会问,不要在控制器中进行交易.将它们放在您的服务层类中."?[来源]

why stack-overflow asked , "Don't do transactions in your controller. Put them in your service layer classes."? [source]

推荐答案

你问的是最佳实践,最佳实践是在服务层标记 @Transactional 因为一个 @Controller 不应该意识到 MVC 逻辑中的数据持久性.
@Service 基于分析生成的用例构建,了解工作单元,也实现了重用方面的思考:如果您从 Web 上下文切换到桌面上下文(例如,或一些其他的视觉前端),其中 @Controller 层不存在你没有问题,因为所有都封装在服务层中.
@Service 是一个契约,表示层的修改不需要重写 @Service 代码.
但是 Spring 并不关心你把你的事务边界放在哪里,你可以放 @Controller 但你的应​​用程序可能会更难维护.

You are asking about best practice, and best practice is to mark @Transactional in the service layer because a @Controller should not be aware of data persistence in a MVC logic.
@Service is constructed on use-case generated from analysis and knows about unit of works and is also realized thinking in terms of reuse: if you switch from a web context to a desktop one (for example, or some other visual frontend) where @Controller layer doesn't exist you don't have problems because all is encapsulated in service layer.
A @Service is a contract and a modification in presentation layer should not require a rewrite of @Service code.
But Spring don't care about where you put your your transaction boundaries, you can put on @Controller but your application may will be harder to be maintained.

我希望这已经足够清楚了.对不起,如果没有;英语不是我的母语.

I hope this is clear enough. Sorry if not; English is not my native language.

这篇关于为什么将@Transactional 与@Service 一起使用而不是与@Controller 一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆