Spring 分层体系结构中的数据交换和事务

Spring 分层体系结构中的数据交换和事务,spring,architecture,transactions,layer,Spring,Architecture,Transactions,Layer,关于这个话题,我读了很多书,但仍然有一些 开放性问题。想象一下下面的场景 [表示层] 您希望开发具有两个访问点的应用程序: web前端(基于视图+控制器) 服务api 因此,将业务逻辑与 这些不同的表示视图可供重用 [数据层] 在分层体系结构的另一端,我们有数据层: 域/模型对象来表示某个ORM框架映射的数据 提供创建、读取、更新、删除(crud)功能的数据访问对象(dao) 这一层是关于访问数据的。保留所有数据访问权限 该层中的特定逻辑,因此它可以很容易地被另一层替代 存储系统 [服

关于这个话题,我读了很多书,但仍然有一些 开放性问题。想象一下下面的场景


[表示层]

您希望开发具有两个访问点的应用程序:

  • web前端(基于视图+控制器)
  • 服务api
因此,将业务逻辑与 这些不同的表示视图可供重用

[数据层]

在分层体系结构的另一端,我们有数据层:

  • 域/模型对象来表示某个ORM框架映射的数据
  • 提供创建、读取、更新、删除(crud)功能的数据访问对象(dao)
这一层是关于访问数据的。保留所有数据访问权限 该层中的特定逻辑,因此它可以很容易地被另一层替代 存储系统

[服务层]

这是介于数据层和表示层之间的层 所有业务逻辑都发生在这里


一方面,我不希望这个线程是特定于语言或框架的, 另一方面,我想知道如何通过中央事务来实现 处理(回滚、提交)。假设我们使用弹簧作为一种方便的工具 事务管理框架

1。处理交易的最佳地点在哪里?

显然,它不是数据访问对象的一部分,因为您希望 在一个事务中访问和更改多个对象。所以 事务处理必须在服务级别上应用,如下所示 由spring框架提出

但假设您的业务逻辑如下所示:

  • a) 从数据库请求一些对象
  • b) 请求有关这些对象的一些远程信息
  • c) 更新数据库中对象的状态
由于操作b可能需要未定义的时间长度,因此您不会 希望在此操作上跨越事务,因为它将分配 宝贵的系统资源。因此,一些业务逻辑必须 与其他人分开

这是否意味着服务层必须分为两层, 一个是事务性的,一个不是???

2。如何修改和检索数据?

为了呈现数据,表示层必须知道 域对象的名称。通过使用DAO,服务层授予 将这些对象的访问权限添加到表示层。我看到两个问题 用这种方法

a) 假设hibernate被用作一个方便的ORM框架。 然后延迟加载依赖项,这对于大多数其他ORM都是如此 框架也是如此。所以我的视图代码试图访问我的复杂对象 可能会出现一些延迟加载异常,因为事务上下文 被服务层终止

处理这种情况的正确方法是什么?

b) 控制器通常使用一些框架魔术来应用 在web表单中直接对模型对象所做的更改。这又是 在任何事务上下文之外,这意味着服务 图层必须提供将模型对象重新附着到新图层的功能 事务并保存它们

这真的是正确的方法吗??


期待您的回答……

我不确定您拥有的体系结构堆栈,但我遇到最多的是Web层>服务层>数据层。也就是说,Web层通过服务层访问数据层。或者,您可以“直接”到服务层以访问数据层

在这些类型的结构中,JTA事务(在启用时)默认配置为参与现有事务或启动自己的事务。在Spring中,这看起来像是在服务层方法上注释的
@Transactional
(例如
updateCustomer
)。如果Web层有一个控制器方法
updateCustomerRequest
,该方法调用服务
updateCustomer
,还调用
createAuditLogEvent
,并且所有这些都必须在一个事务中完成,则Web层启动事务,服务层参与其中,事务在
createAuditLogEvent
之后在Web层完成。如果直接调用了服务层的
updateCustomer
,则transactionManager仅围绕
updateCustomer
方法启动一个新事务


因此,通过使用一种模型,即服务层是您对数据层的“最低访问级别”,Web层通过服务层重用/访问,事务可以在各个层之间共享。

我不确定您拥有的体系结构堆栈,但我遇到的最多的是Web层>服务层>数据层。也就是说,Web层通过服务层访问数据层。或者,您可以“直接”到服务层以访问数据层

在这些类型的结构中,JTA事务(在启用时)默认配置为参与现有事务或启动自己的事务。在Spring中,这看起来像是在服务层方法上注释的
@Transactional
(例如
updateCustomer
)。如果Web层有一个控制器方法
updateCustomerRequest
,该方法调用服务
updateCustomer
,还调用
createAuditLogEvent
,并且所有这些都必须在一个事务中完成,则Web层启动事务,服务层参与其中,事务在
createAuditLogEvent
之后在Web层完成。如果直接调用了服务层的
updateCustomer
,则transactionManager仅围绕
updateCustomer
方法启动一个新事务

所以,通过使用一个模型