Spring 框架事务支持模型的优势
传统上,EE 应用程序开发人员在事务管理方面有两种选择:全局事务或本地事务,这两者都有深刻的局限性。接下来的两个部分将回顾全局和本地事务管理,随后将讨论 Spring 框架的事务管理支持如何解决全局和本地事务模型的局限性。
全局事务
全局事务允许您处理多个事务性资源,通常是关系数据库和消息队列。应用服务器通过 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 Framework 的事务抽象,这可以在任何底层事务基础设施上运行。使用首选的声明式模型时,开发人员通常很少编写与事务管理相关的代码,因此不依赖于 Spring Framework 的事务 API 或任何其他事务 API。