【问题标题】:Where should "@Transactional" be placed Service Layer or DAO“@Transactional”应该放在哪里服务层或DAO
【发布时间】:2011-04-22 15:54:04
【问题描述】:

首先,我可能会问一些以前被问过和回答过的问题,但我无法得到搜索结果。我们在服务层上定义事务注解,典型的 spring hibernate crud 通常是

Controller->Manager->Dao->Orm.

我现在遇到需要在基于客户端站点的域模型之间进行选择的情况。 假设客户端 A 正在使用我的域模型,一切都很好,但是其他客户端站点会给我一个 Web 服务,而不是使用我们的域模型。

我应该更换哪一层。我相信它必须是 DAO,它将从 Web 服务获取我的数据并将其发送回。即两个单独编写的 DAO 层并根据场景插入。

我现在意识到,当我们将@Transactional 放在服务层时,我们一直在做紧耦合(如果有这样的事情或者说没有松耦合)。这么多的大脑不可能是错的,或者他们是错的(我怀疑)。

所以问题是“应该将“@Transactional”放置在服务层还是 DAO 的位置​​?”我应该更换向下的服务层吗?


11 年过去了,仍然有意义。如果我回顾这个项目,我当时对域模型的理解显然是错误的。我将 ORM 层视为域模型,我们希望使用 ORM 和分离实体,并且没有任何数据映射,也没有任何 DTO。那是当时的趋势。如今,域模型不是 ORM,拥有适当的域模型并使用 ORM 或 Web 服务是数据源来解决这个问题。就像许多人指出的那样,是的,服务是它的正确位置,并且具有适当的域模型,而不是将 JPA (ORM) 视为域模型。

【问题讨论】:

标签: spring transactions dao


【解决方案1】:

理想情况下,服务层 (Manager) 代表您的业务逻辑,因此应使用 @Transactional 进行注释。

服务层可能会调用不同的 DAO 来执行 DB 操作。让我们假设一个服务方法中有 3 个 DAO 操作。如果您的第一个 DAO 操作失败,其他两个可能仍会通过,最终您将获得不一致的数据库状态。注释服务层可以让您避免这种情况。

【讨论】:

  • 感谢您的回复。你能说一下你回复的年份吗?信不信由你,我想你可能刚刚证明了时间机器的存在。 2015 年给你 +1。
  • 直到你问我才注意到年份:)
【解决方案2】:

您将希望您的服务具有事务性。如果您的 DAO 是事务性的,并且您在每个服务中调用不同的 DAO,那么您将有多个事务,这不是您想要的。使服务调用具有事务性,这些方法中的所有 DAO 调用都将参与该方法的事务。

【讨论】:

  • 他不能在@Transaction 注释上指定传播方法,以便只使用 1 个事务,因为它在 here 中列出
  • @FotisParaskevopoulos 只有当他在both 服务和 DAO 上都有@Transactional 时才会起作用。那么额外的注释不会受到伤害,但也无济于事。
【解决方案3】:

我建议将 @Transactional 放在服务层方法中,因为我们可以有多个 DAO 实现。通过使用它,我们可以使我们的服务成为事务性的。 refer

最佳实践是使用通用 BasicService 来提供通用服务。

Service 是放置@Transactional 的最佳位置,服务层应保存在逻辑上进入事务的用户交互的详细级用例行为。通过这种方式,我们可以保持 Web 应用程序代码和业务逻辑之间的分离。

有很多 CRUD 应用程序没有任何重要的业务逻辑,因为它们有一个服务层,只是在控制器和数据访问对象之间传递东西是没有用的。在这些情况下,我们可以在 Dao 上放置事务注解。

所以实际上你可以把它们放在任何一个地方,这取决于你。

通过在您的服务中进行多次调用,您需要在服务中使用 @Transactional。如果您将 @Transactional 置于服务中,则对服务的不同调用将在不同的事务中执行。

【讨论】:

    【解决方案4】:

    这是基于应用程序类型的个人选择,如果应用程序跨多个模块分层并且大多数操作是基于 @CRUD 的,那么在服务级别使用 @transactional 注释会更有意义.. 引擎类型的应用程序,如调度程序、作业服务器,@etl 报告应用程序,其中不存在会话和用户概念,那么在上下文级别的传播事务是最合适的......我们不应该通过将@transactional 放在每个地方最终创建事务性反模式来创建集群事务......无论如何对于务实的事务控制,JTA2 是最合适的答案...再次取决于天气,您可以在给定的情况下使用它...

    【讨论】:

      【解决方案5】:

      你应该在服务层使用@Transactional,如果你想改变客户端B的域模型,你必须在不同的模型中提供相同的数据,你可以通过提供一个在不影响DAO层的情况下改变域模型不同的服务或通过创建接口并在不同的模型中实现接口并使用相同的服务填充基于客户端的模型。此决定基于业务需求和项目范围。

      【讨论】:

        【解决方案6】:

        我在编程课上听说,dao层负责与数据库交互,服务是一组操作可能与dao有关,因此数据库与否,并且该组操作在一个事务中,意思更好服务是事务性的。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-01-29
          • 2015-01-07
          • 1970-01-01
          • 2020-11-22
          • 2013-06-12
          • 1970-01-01
          • 2013-09-09
          • 1970-01-01
          相关资源
          最近更新 更多