spring事务管理一:spring事务管理的优点
(翻译自spring-framework-reference.pdf 第四章 Data Access)
通常情况下,J2EE有2种事务管理方式:全局事务和本地事务,2种事务都比较明显的缺陷。
全局事务:
全局事务允许跨多个事务资源的事务管理(通常是关系数据库和消息队列),应用服务器通过JTA(一个很复杂的api)管理全局事务,此外,一个JTA的事务通常通过JNDI进行资源查找,即如果你想使用JTA就必须连带使用JNDI。JTA通常只能在应用服务器环境下使用,显然使用全局事务会限制应用代码的重用性。
更好的方式是通过EJB CMT提供全局事务管理,CMT是一种声明式的事务管理。EJB CMT移除了事务相关的JNDI查找,虽然使用EJB本身就需要使用JNDI,但这确实节省了大量的事务管理代码(并不是全部),重大缺陷是CMT绑定在JTA以及应用服务器环境上,并且你必须选择EJB来处理业务逻辑。EJB太庞大,并不是一个很吸引人的选择(仅仅是为了增加全局事务就使用EJB,确实....)。
本地事务:
本地事务则和底层所使用的持久化技术有关(使用JDBC处理持久化,事务管理需要JDBC中的connection对象,使用hibernate处理持久化,事务管理需要hibernate中的session对象),比起全局事务,本地事务更易使用,但是也有明显的缺陷:1,不能跨事务资源,例如:使用JDBC事务来进行事务管理的代码在JTA全局事务环境下就不能运行。2,使用本地事务,由于应用服务器不需要参与事务的管理,因此不能保证跨多个事务性资源的事务正确性(不需要特别注意这种情况,大多数应用使用单个事务资源)。3,显然事务管理和代码是耦合的,具有侵入性(这也是前面缺陷1的产生原因)。
spring事务管理:
spring解决了全局事务和本地事务的缺陷,允许应用开发者在任何环境下使用一致的编程模型。spring同时支持编程式事务管理和声明式事务管理。当使用spring编程式事务管理时,开发者直接使用spring框架的事务抽象(事务抽象这个翻译有点拗口,原文为:transaction abstraction,不同具体事务策略的统一抽象接口,面向接口编程),使应用程序可以运行在任何具体的底层事务基础之上。当使用spring声明式事务管理时,只需编写少量和事务相关的代码即可(只需编写一些spring配置文件),这些代码和spring的事务api或任何其他的事务api都没有耦合。显然spring的声明式事务管理更加简单易用。
问题:为了使用事务管理是否应该选择应用服务器?
答案是否定的。
spring对事务管理的支持改变了企业级JAVA应用必须要使用应用服务器的传统观念。需要特别指出的是,仅仅是为了使用EJB的声明式事务管理就选择使用应用服务器是完全没有必要的(为了使用声明式事务管理就使用EJB同样可怕),尽管应用服务器提供了强劲的JTA功能,spring的声明式事务管理比起EJB CMT更加给力,并且提供更加高效的编程方式。通常选择使用应用服务器是为了跨多个事务资源的事务管理,这种情况很少见并且许多高端应用会选择使用高性能数据库而不是多个事务资源。也可以选择一些独立的事务管理技术,但是大多数情况下这些技术都需要一些应用服务器功能(比如JMS或是JCA)的支持。spring更符合一次编写,随处运行的原则,代价仅仅是修改一些spring配置文件,而不是大量的重复性编码工作。