spring事务管理.doc
《spring事务管理.doc》由会员分享,可在线阅读,更多相关《spring事务管理.doc(28页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、9.5.声明式事务管理大多数Spring用户选择声明式事务管理。这是对应用代码影响最小的选择,因此也最符合 非侵入式 轻量级容器的理念。Spring的声明式事务管理是通过Spring AOP实现的,因为事务方面的代码与Spring绑定并以一种样板式风格使用,不过尽管如此,你一般并不需要理解AOP概念就可以有效地使用Spirng的声明式事务管理。从考虑EJB CMT和Spring声明式事务管理的相似以及不同之处出发是很有益的。它们的基本方法是相似的:都可以指定事务管理到单独的方法;如果需要可以在事务上下文调用 setRollbackOnly() 方法。不同之处在于: 不像EJB CMT绑定在JT
2、A上,Spring声明式事务管理可以在任何环境下使用。只需更改配置文件,它就可以和JDBC、JDO、Hibernate或其他的事务机制一起工作。 Spring的声明式事务管理可以被应用到任何类(以及那个类的实例)上,不仅仅是像EJB那样的特殊类。 Spring提供了声明式的回滚规则:EJB没有对应的特性,我们将在下面讨论。回滚可以声明式的控制,不仅仅是编程式的。 Spring允许你通过AOP定制事务行为。例如,如果需要,你可以在事务回滚中插入定制的行为。你也可以增加任意的通知,就象事务通知一样。使用EJB CMT,除了使用setRollbackOnly(),你没有办法能够影响容器的事务管理。
3、Spring不提供高端应用服务器提供的跨越远程调用的事务上下文传播。如果你需要这些特性,我们推荐你使用EJB。然而,不要轻易使用这些特性。通常我们并不希望事务跨越远程调用。TransactionProxyFactoryBean在哪儿?Spring2.0及以后的版本中声明式事务的配置与之前的版本有相当大的不同。主要差异在于不再需要配置TransactionProxyFactoryBean了。Spring2.0之前的旧版本风格的配置仍然是有效的;你可以简单地认为新的替你定义了TransactionProxyFactoryBean。回滚规则的概念比较重要:它使我们能够指定什么样的异常(和throwa
4、ble)将导致自动回滚。我们在配置文件中声明式地指定,无须在Java代码中。同时,我们仍旧可以通过调用 TransactionStatus 的 setRollbackOnly() 方法编程式地回滚当前事务。通常,我们定义一条规则,声明 MyApplicationException 必须总是导致事务回滚。这种方式带来了显著的好处,它使你的业务对象不必依赖于事务设施。典型的例子是你不必在代码中导入Spring API,事务等。对EJB来说,默认的行为是EJB容器在遇到 系统异常(通常指运行时异常)时自动回滚当前事务。EJB CMT遇到 应用异常(例如,除了 java.rmi.RemoteExcep
5、tion 外别的checked exception)时并不会自动回滚。默认式Spring处理声明式事务管理的规则遵守EJB习惯(只在遇到unchecked exceptions时自动回滚),但通常定制这条规则会更有用。9.5.1.理解Spring的声明式事务管理实现本节的目的是消除与使用声明式事务管理有关的神秘性。简单点儿总是好的,这份参考文档只是告诉你给你的类加上Transactional注解,在配置文件中添加()行,然后期望你理解整个过程是怎么工作的。此节讲述Spring的声明式事务管理内部的工作机制,以帮助你在面对事务相关的问题时不至于误入迷途,回朔到上游平静的水域。提示阅读Spring
6、源码是理解清楚Spring事务支持的一个好方法。Spring的Javadoc提供的信息丰富而完整。我们建议你在开发自己的Spring应用时把日志级别设为DEBUG级,这样你能更清楚地看到幕后发生的事。在理解Spring的声明式事务管理方面最重要的概念是:Spring的事务管理是通过AOP代理实现的。其中的事务通知由元数据(目前基于XML或注解)驱动。代理对象与事务元数据结合产生了一个AOP代理,它使用一个PlatformTransactionManager实现品配合TransactionInterceptor,在方法调用前后实施事务。注意尽管使用Spring声明式事务管理不需要AOP(尤其是S
7、pring AOP)的知识,但了解这些是很有帮助的。你可以在 章找到关于Spring AOP的全部内容。概念上来说,在事务代理上调用方法的工作过程看起来像这样:9.5.2.第一个例子请看下面的接口和它的实现。这个例子的意图是介绍概念,使用 Foo 和 Bar 这样的名字只是为了让你关注于事务的用法,而不是领域模型。 package x.y.service;public interface FooService Foo getFoo(String fooName); Foo getFoo(String fooName, String barName); void insertFoo(Foo fo
8、o); void updateFoo(Foo foo); package x.y.service;public class DefaultFooService implements FooService public Foo getFoo(String fooName) throw new UnsupportedOperationException(); public Foo getFoo(String fooName, String barName) throw new UnsupportedOperationException(); public void insertFoo(Foo fo
9、o) throw new UnsupportedOperationException(); public void updateFoo(Foo foo) throw new UnsupportedOperationException(); (对该例的目的来说,上例中实现类(DefaultFooService)的每个方法在其方法体中抛出 UnsupportedOperationException 的做法是恰当的,我们可以看到,事务被创建出来,响应 UnsupportedOperationException 的抛出,然后回滚。) 我们假定,FooService的前两个方法(getFoo(Strin
10、g)和getFoo(String, String))必须执行在只读事务上下文中,其余方法(insertFoo(Foo)和updateFoo(Foo))必须执行在读写事务上下文中。使用XML方式元数据的声明式配置的话,你得这么写(不要想着一次全部理解,所有内容会在后面的章节详细讨论): !- the transactional advice (i.e. what happens; see the bean below) - !- other definitions here - 我们来分析一下上面的配置。我们要把一个服务对象(fooService bean)做成事务性的。我们想施加的事务语义封装
11、在定义中。 “把所有以 get 开头的方法看做执行在只读事务上下文中,其余的方法执行在默认语义的事务上下文中”。 其中的 transaction-manager 属性被设置为一个指向 PlatformTransactionManager bean的名字(这里指 txManager),该bean将实际上实施事务管理。提示事实上,如果 PlatformTransactionManager bean的名字是 transactionManager 的话,你的事务通知()中的 transaction-manager 属性可以忽略。否则你则需要像上例那样明确指定。配置中最后一段是 的定义,它确保由 txA
12、dvice bean定义的事务通知在应用中合适的点被执行。首先我们定义了 一个切面,它匹配 FooService 接口定义的所有操作,我们把该切面叫做 fooServiceOperation。然后我们用一个通知器(advisor)把这个切面与 txAdvice 绑定在一起,表示当 fooServiceOperation 执行时,txAdvice 定义的通知逻辑将被执行。 元素定义是AspectJ的切面表示法,可参考Spring 2.0 章获得更详细的内容。一个普遍性的需求是让整个服务层成为事务性的。满足该需求的最好方式是让切面表达式匹配服务层的所有操作方法。例如: (这个例子中假定你所有的服务
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- spring 事务管理
限制150内