|
对于最新稳定版本,请使用 Spring Framework 7.0.6! |
Spring 框架事务支持模型的优势
传统上,Java EE 应用程序开发人员在事务管理方面只有两种选择:全局事务或本地事务,而这两者都存在明显的局限性。接下来的两节将分别回顾全局事务和本地事务管理,随后讨论 Spring 框架的事务管理支持如何解决全局和本地事务模型的局限性。
全局事务
全局事务允许您操作多个事务性资源,通常包括关系型数据库和消息队列。应用服务器通过 JTA(Java Transaction API)来管理全局事务,而 JTA 是一个繁琐的 API(部分原因在于其异常模型)。此外,JTA 的 UserTransaction 通常需要从 JNDI 获取,这意味着您必须使用 JNDI 才能使用 JTA。全局事务的使用限制了应用程序代码的潜在重用性,因为 JTA 通常仅在应用服务器环境中可用。
过去,使用全局事务的首选方式是通过 EJB CMT(容器管理事务)。CMT 是一种声明式事务管理形式(区别于编程式事务管理)。EJB CMT 消除了与事务相关的 JNDI 查找需求,尽管使用 EJB 本身仍需要使用 JNDI。它消除了大部分(但并非全部)编写 Java 代码来控制事务的需求。然而,其显著缺点在于 CMT 与 JTA 和应用服务器环境紧密绑定。此外,只有在选择使用 EJB 实现业务逻辑(或至少通过一个事务性的 EJB 外观层)时,CMT 才可用。鉴于 EJB 整体上存在诸多弊端,这一方案并不具吸引力,尤其是在当前已有极具竞争力的声明式事务管理替代方案的情况下。
本地事务
本地事务是特定于资源的,例如与 JDBC 连接关联的事务。本地事务可能更易于使用,但有一个明显的缺点:它们无法跨多个事务性资源工作。例如,使用 JDBC 连接管理事务的代码无法在全局 JTA 事务中运行。由于应用服务器不参与事务管理,因此无法帮助确保跨多个资源的一致性。(值得注意的是,大多数应用程序仅使用单一事务资源。)另一个缺点是,本地事务会对编程模型造成侵入性影响。
Spring Framework 的一致编程模型
Spring 解决了全局事务和本地事务的缺点。它允许应用程序开发人员在任何环境中使用一致的编程模型。 你只需编写一次代码,即可在不同环境中受益于不同的事务管理策略。Spring 框架同时提供了声明式和编程式事务管理。 大多数用户更倾向于声明式事务管理,我们在大多数情况下也推荐使用这种方式。
使用编程式事务管理时,开发人员直接使用 Spring Framework 的事务抽象层,该抽象层可以在任何底层事务基础设施之上运行。 而在更推荐的声明式模型中,开发人员通常只需编写很少甚至无需编写与事务管理相关的代码,因此不依赖于 Spring Framework 的事务 API 或任何其他事务 API。