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

传统上,EE 应用开发者在事务管理方面只有两种选择:全局事务或本地事务,两者都存在着严重的局限性。接下来的两节将回顾全局和本地事务管理,并讨论 Spring 框架的事务管理支持如何解决全局和本地事务模型的局限性。

全局事务

全局事务允许您操作多个事务资源,通常是关系型数据库和消息队列。应用服务器通过 JTA 管理全局事务,JTA 是一个笨重的 API(部分原因是其异常模型)。此外,JTA 的 UserTransaction 通常需要从 JNDI 获取,这意味着您还需要使用 JNDI 才能使用 JTA。全局事务的使用限制了应用程序代码的潜在重用,因为 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 定义(而不是代码)。