Spring 框架事务支持模型的优势

传统上,EE 应用开发人员有两种事务管理选择:全局事务或局部事务,两者都有深刻的局限性。接下来的两节将回顾全局事务和局部事务管理,然后讨论 Spring 框架的事务管理支持如何解决全局和局部事务模型的局限性。

全局事务

全局事务允许您使用多个事务性资源,通常是关系数据库和消息队列。应用服务器通过 JTA 管理全局事务,JTA 是一个繁琐的 API(部分原因在于其异常模型)。此外,JTA `UserTransaction` 通常需要从 JNDI 获取,这意味着要使用 JTA,您还需要使用 JNDI。全局事务的使用限制了应用代码的任何潜在重用,因为 JTA 通常仅在应用服务器环境中可用。

以前,使用全局事务的首选方式是通过 EJB CMT(容器管理事务)。CMT 是一种声明式事务管理形式(与编程式事务管理不同)。EJB CMT 消除了事务相关的 JNDI 查找需求,尽管使用 EJB 本身也需要使用 JNDI。它消除了大部分但不是全部编写 Java 代码来控制事务的需要。显著的缺点是 CMT 绑定到 JTA 和应用服务器环境。此外,只有当选择在 EJB 中实现业务逻辑(或至少在事务性 EJB 外观之后)时,它才可用。总的来说,EJB 的缺点非常大,因此这不是一个有吸引力的选择,尤其是在声明式事务管理存在引人注目的替代方案的情况下。

局部事务

局部事务是资源特定的,例如与 JDBC 连接关联的事务。局部事务可能更容易使用,但有一个显著的缺点:它们不能跨越多个事务性资源工作。例如,使用 JDBC 连接管理事务的代码不能在全局 JTA 事务中运行。由于应用服务器不参与事务管理,它无法帮助确保跨多个资源的正确性。(值得注意的是,大多数应用程序使用单个事务资源。)另一个缺点是局部事务对编程模型具有侵入性。

Spring 框架的一致编程模型

Spring 解决了全局事务和局部事务的缺点。它允许应用开发人员在任何环境中使用一致的编程模型。您只需编写一次代码,它就可以从不同环境中的不同事务管理策略中获益。Spring 框架提供了声明式和编程式事务管理。大多数用户更喜欢声明式事务管理,我们在大多数情况下也推荐使用它。

使用编程式事务管理时,开发人员使用 Spring 框架事务抽象,该抽象可以在任何底层事务基础设施之上运行。使用首选的声明式模型时,开发人员通常编写很少或不编写与事务管理相关的代码,因此不依赖于 Spring 框架事务 API 或任何其他事务 API。

事务管理是否需要应用服务器?

Spring 框架的事务管理支持改变了企业 Java 应用何时需要应用服务器的传统规则。

特别是,您不再仅仅为了通过 EJB 实现声明式事务而需要应用服务器。实际上,即使您的应用服务器具有强大的 JTA 能力,您也可能决定 Spring 框架的声明式事务比 EJB CMT 提供更多的功能和更高效的编程模型。

通常,只有当您的应用程序需要跨多个资源处理事务时,才需要应用服务器的 JTA 能力,而这对于许多应用程序来说并不是必需的。许多高端应用会使用单个、高度可伸缩的数据库(如 Oracle RAC)来代替。独立的事务管理器(如 Atomikos Transactions)是其他选择。当然,您可能需要应用服务器的其他功能,例如 Java 消息服务 (JMS) 和 Jakarta EE 连接器架构 (JCA)。

Spring 框架让您可以自由选择何时将应用扩展到功能齐全的应用服务器。那种除了使用 EJB CMT 或 JTA 之外,只能用局部事务(例如基于 JDBC 连接的事务)编写代码,并且在需要将这些代码运行在全局、容器管理事务中时面临大量返工的日子已经一去不复返了。使用 Spring 框架,只需更改配置文件中的某些 bean 定义(而不是代码)。