Spring框架事务支持模型的优势
传统上,EE(Enterprise Edition)应用程序开发人员在事务管理方面有两种选择:全局事务和本地事务,但两者都存在严重的局限性。接下来的两节将分别探讨全局事务和本地事务管理,随后会讨论Spring框架的事务管理支持是如何克服这些局限性的。
全局事务
全局事务允许你操作多个事务资源,通常是关系型数据库和消息队列。应用程序服务器通过JTA来管理全局事务,而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框架的一致编程模型
Spring解决了全局事务和本地事务的缺点。它让应用程序开发者能够在任何环境中使用一致的编程模型。你只需编写一次代码,就可以在不同环境中享受到不同的事务管理策略带来的好处。Spring框架提供了声明式和程序式两种事务管理方式。大多数用户更喜欢声明式事务管理,在大多数情况下我们也推荐使用这种方式。
通过程序化事务管理,开发者可以利用Spring框架的事务抽象层,该抽象层可以运行在任何底层事务基础设施之上。由于采用了声明性模型,开发者通常不需要编写与事务管理相关的代码,因此他们也不必依赖于Spring框架的事务API或其他任何事务API。