【问题标题】:Transactional: controller vs service事务性:控制器与服务
【发布时间】:2011-05-26 15:43:31
【问题描述】:

假设我有一个控制器方法get(),它调用了一些使用数据库的服务方法。

将整个控制器方法设置为事务性还是只设置每个服务方法是否正确?

在我看来,我们必须使get() 具有事务性,因为它执行相关操作。

【问题讨论】:

    标签: transactions spring-mvc


    【解决方案1】:

    我更喜欢仅将需要事务性的服务方法设为事务性,并控制服务中的事务性而不是控制器中的事务性。您可以创建一个包含其他服务方法的服务方法,并使用 spring 事务通过 @Transactional 注释中的传播来管理事务。

    @Transactional(propagation =...)
    

    编辑

    如果我有 2 种方法,例如 saveUser() 和 saveEmail()(因为我将电子邮件存储在数据库中以便稍后发送它们 - 就像一个队列)我会在我的服务中创建一个方法 saveUserAndSendEmail(User user) 这将交易。此方法将在 @Repository 组件中分别调用 saveUser 和 saveEmail() ,因为它们处理数据库。所以我会将它们放在@Repository 组件中处理数据库的方法,然后我控制@Service 组件中的事务性。然后控制器将只需要担心提供数据并在需要时调用。但是我做一个事务是因为我不想在整个方法执行成功之前提交数据库中的更改。

    但这是我通常使用的风格,我并不是说这一定是要走的路。

    【讨论】:

    • 这似乎是首选设计,但为什么呢?考虑我需要 loadMenuItems()、loadUserInfo()、loadDocument() - 很多方法。根据你的说法,我必须创建一个 loadMenuItemsAndUserInfoAndDocument() 方法 - 可以吗?
    • @Andrey 我没有说这是首选设计。这是我通常的工作方式,因为我更喜欢控制器不需要了解事务管理。根据您的方法名称以 load 开头...如果它们仅来自数据库,为什么需要进行事务处理?
    • 好吧,如果你有两种方法:createUser()、sendEmail(),来自不同的服务(用户和邮件)。您需要在事务控制器中同时调用它们。你应该怎么做?
    • @Aundrey 我已经用两种方法编辑了这个问题,因为它们都需要在数据库中持久化数据。
    【解决方案2】:

    这完全取决于您,以及您如何解释自己的业务逻辑。

    Spring 并不真正关心您将事务边界放在哪里,当然也不限制您将它们放在您的 DAO 类中。

    所以是的,将@Transactional 添加到您的控制器方法中是完全有效的。

    【讨论】:

    • 恕我直言,控制器中的@Transactional 从架构角度 (MVC) 没有太多意义。我的意思是,控制器不应该知道持久层,并且您可能不得不在您的控制器层不再存在的桌面应用程序中重用您的业务逻辑......我认为事务性应该在 @Service 层中定义。
    • 从语言角度来看完全有效。但是,如果您考虑将控制器方法绑定到某些数据库操作,这不是一个好习惯。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    相关资源
    最近更新 更多