Advantages of the Spring Framework’s Transaction Support Model
传统上,EE应用程序开发人员在事务管理方面有两个选择:全局事务或本地事务,两者都有很大的局限性。在接下来的两节中对全局和本地事务管理进行了回顾,接着讨论了Spring Framework的事务管理支持如何解决全局和本地事务模型的局限性。
Global Transactions
全局事务让您使用多个事务资源,通常是关系数据库和消息队列。应用程序服务器通过JTA来管理全局事务,它是一个繁琐的API(部分原因是它的异常模型)。此外,JTA`UserTransaction`通常需要从JNDI获取,这意味着您还需要使用JNDI才能使用JTA。使用全局事务限制了应用程序代码的任何潜在重复使用,因为通常只有在应用服务器环境中才能使用JTA。
以前,使用全局事务的首选方法是通过EJB CMT(容器管理事务)。CMT是一种声明式事务管理形式(区别于程序化事务管理)。EJB CMT消除了与事务相关的JNDI查找的需要,尽管使用EJB本身需要使用JNDI。它消除了大部分(但不是全部)编写Java代码控制事务的需要。显著的缺点是CMT与JTA和应用服务器环境相关联。此外,只有在选择在EJB中(或至少在事务性EJB外观后面)实现业务逻辑时才可以使用它。整体而言EJB的缺点非常大,因此这不是一个有吸引力的命题,尤其是在考虑到声明式事务管理引人注目的替代方案时。
Local Transactions
本地事务是特定于资源的,例如与JDBC连接相关联的事务。本地事务可能更易于使用,但有一个重大缺点:它们无法跨多个事务资源工作。例如,通过使用JDBC连接管理事务的代码不能在全局JTA事务中运行。因为应用程序服务器未参与事务管理,所以它无法帮助确保跨多个资源的正确性。(值得注意的是,大多数应用程序使用单个事务资源。)另一个缺点是本地事务会侵入编程模型。
Spring Framework’s Consistent Programming Model
Spring解决了全局和本地事务的缺点。它让应用程序开发人员可以在任何环境中使用一致的编程模型。您编写代码一次,它就可以从不同的环境中受益于不同的事务管理策略。Spring Framework提供了声明式和程序化事务管理。大多数用户更喜欢声明式事务管理,我们大多数情况下也推荐使用它。
使用程序化事务管理时,开发人员可以使用Spring Framework事务抽象,它可以在任何底层事务基础设施上运行。使用首选的声明式模型时,开发人员通常编写很少或根本不编写与事务管理相关联的代码,因此不依赖于Spring Framework事务API或任何其他事务API。
Spring Framework的事务管理支持改变了传统规则,即何时企业Java应用程序需要一个应用服务器。 具体来说,您不需要一个仅用于通过EJB进行声明式事务的应用服务器。事实上,即使您的应用程序服务器有强大的JTA功能,您也可能决定Spring Framework的声明式事务比EJB CMT提供了更强大的功能和更高的生产力编程模型。 通常,仅当你的应用程序如果需要跨多个资源处理事务(对于很多应用程序来说这不是一个要求),你才需要应用程序服务器的 JTA 功能。很多高端应用程序反而使用一个高度可扩展的数据库(如 Oracle RAC)。独立事务管理器(如 Atomikos Transactions)是另一种选择。当然,你可能需要其它应用程序服务器功能,如 Java 消息服务 (JMS) 和 Jakarta EE 连接器架构 (JCA)。 Spring Framework让您可以选择何时将应用程序扩展到一个完全加载的应用程序服务器。现在已经一去不复返了,因为唯一的选择是使用EJB CMT或JTA是编写具有本地事务的代码(例如那些在JDBC连接上),并且如果您需要该代码在全局容器管理事务中运行时,您将面临繁重的返工。使用Spring Framework,配置文件中只需要更改一些bean定义(而不是您的代码)。