Spring备忘——事务管理(声明式事务管理)

3.2<wbr></wbr>声明式事务管理

声明式事务管理是通过Spring AOP实现的。

大多数Spring用户选择声明式事务管理。这是最少影响应用代码的选择,因而这是和非侵入性的轻量级容器的观念是一致的。

从考虑EJB CMTSpring声明式事务管理的相似以及不同之处出发是很有益的。它们的基本方法是相似的:都可以指定事务管理到单独的方法;如果需要可以在事务上下文调用setRollbackOnly()方法。不同之处如下:

·<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>不象EJB CMT绑定在JTA上,Spring声明式事务管理可以在任何环境下使用。只需更改配置文件,它就可以和JDBCJDOHibernate或其他的事务机制一起工作

·<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>Spring可以使声明式事务管理应用到普通Java对象,不仅仅是特殊的类,如EJB

·<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>Spring提供声明式回滚规则EJB没有对应的特性,我们将在下面讨论这个特性。回滚可以声明式控制,不仅仅是编程式的

·<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>Spring允许你通过AOP定制事务行为。例如,如果需要,你可以在事务回滚中插入定制的行为。你也可以增加任意的通知,就像事务通知一样。使用EJBCMT,除了使用setRollbackOnly(),你没有办法能够影响容器的事务管理

·<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>Spring不提供高端应用服务器提供的跨越远程调用的事务上下文传播。如果你需要这些特性,我们推荐你使用EJB。然而,不要轻易使用这些特性。通常我们并不希望事务跨越远程调用

回滚规则的概念是很重要的:它们使得我们可以指定哪些异常应该发起自动回滚。我们在配置文件中以声明的方式指定。因此,虽然我们仍然可以编程调用TransactionStatus对象的setRollbackOnly()方法来回滚当前事务,多数时候我们可以指定规则,如MyApplicationException应该导致回滚。这有显著的优点,业务对象不需要依赖事务基础设施。例如,它们通常不需要引入任何Spring API,事务或其他任何东西。

EJB的默认行为是遇到系统异常(通常是运行时异常),EJB容器自动回滚事务。EJB CMT遇到应用程序异常(除了java.rmi.RemoteException外的checked异常)时不 会自动回滚事务。虽然Spring声明式事务管理沿用EJB的约定(遇到unchecked 异常自动回滚事务),但是这是可以定制的。

按照我们的测试,Spring声明式事务管理的性能要胜过EJB CMT

通常通过TransactionProxyFactoryB<wbr>ean</wbr>设置Spring事务代理。我们需要一个目标对象包装在事务代理中。这个目标对象一般是一个普通Java对象的bean。当我们定义TransactionProxyFactoryB<wbr>ean</wbr>时,必须提供一个相关的 PlatformTransactionManag<wbr>er</wbr>的引用和事务属性事务属性含有上面描述的事务定义。

<>
<wbr><wbr><wbr><wbr> lang="EN-US" style="font-size:9pt"&gt;<span style="font-family:宋体"><wbr><wbr><wbr></wbr></wbr></wbr></span></wbr></wbr></wbr></wbr>
<wbr><wbr><wbr></wbr></wbr></wbr>
<wbr><wbr><wbr></wbr></wbr></wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> PROPAGATION_REQUIRED,-MyCheckedException</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr>PROPAGATION_REQUIRED</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr> PROPAGATION_REQUIRED,readOnly</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
<wbr><wbr><wbr><wbr><wbr><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
<wbr><wbr><wbr></wbr></wbr></wbr>

intPROPAGATION_REQUIRED=0表示当前方法必须运行在事务中。如果调用它的客户在事务中,则当前方法直接使用该事务,否则启新事务。

intPROPAGATION_SUPPORTS=1表示当前方法可以运行在事务中,也可以不运行在事务中。

intPROPAGATION_MANDATORY=2表示当前方法必须运行在事务中。如果调用它的客户不在事务中,则抛出异常。

int PROPAGATION_REQUIRES_NEWS =3表示当前方法必须运行在事务中。无论客户如何,都要启新事务。

int PROPAGATION_NOT_SUPPORTED =4表示当前方法不能运行在事务中。如果客户处于事务中,执行到该业务方法时,事物要挂起。

int PROPAGATION_ NEVER=5表示调用当前方法的客户不能够处于事务中,否则将抛出异常。

int PROPAGATION_NESTED=6 表明当前方法支持事务嵌套。

事务代理会实现目标对象的接口:这里是idpetStoreTargetbean。(使用 CGLIB也可以实现具体类的代理。只要设置proxyTargetClass属性为true就可以。 如果目标对象没有实现任何接口,这将自动设置该属性为true。通常,我们希望面向接口而不是类编程。)使用proxyInterfaces属性来限定事务代理来代理指定接口也是可以的(一般来说是个好想法)。也可以通过从org.springframework.aop.framework.ProxyConfig继承或所有AOP代理工厂共享的属性来定制TransactionProxyFactoryB<wbr>ean</wbr>的行为。

这里的transactionAttributes属性定义在org.springframework.transaction.interceptor.NameMatchTransactionAttr<wbr>ibuteSource</wbr>中的属性格式来设置。这个包括通配符的方法名称映射是很直观的。拦截器会按照规则拦截业务方法。注意insert*的映射的值包括回滚规则。添加的-MyCheckedException 指定如果方法抛出MyCheckedException或它的子类,事务将会自动回滚。可以用逗号分隔定义多个回滚规则。-前缀强制回滚,+前缀指定提交(这允许即使抛出unchecked异常时也可以提交事务,当然你自己要明白自己在做什么)。

注:insert*表示petStoreTarget业务类中所有以insert开头的业务方法。

<wbr></wbr><wbr></wbr>注:切入点是业务类的方法!拦截器也是拦截到方法!

TransactionProxyFactoryB<wbr>ean</wbr>允许你通过 “preInterceptors”“postInterceptors”属性设置通知来提供额外的拦截行为。可以设置任意数量的通知,它们的类型可以是 Advisor(可以包含一个切入点),MethodInterceptor或被当前Spring配置支持的通知类型 (例如ThrowAdvice AfterReturningtAdviceBeforeAdvice,这些都是默认支持的)。这些通知必须支持实例共享模式。如果你需要高级AOP特性来使用事务,如有状态的maxin,那最好使用通用的 org.springframework.aop.framework.ProxyFactoryBean,而不是TransactionProxyFactoryB<wbr>ean</wbr>实用代理创建者。

也可以设置自动代理:配置AOP框架,不需要单独的代理定义类就可以生成类的代理。

ES的架构中,事务是这样实现的:

<!—首先定义一个事务代理的抽象父类-->

"txProxyTemplate" abstract="true"

<wbr><wbr><wbr>lang="EN-US"style="font-size:10pt;background:white;color:blue;font-family:'CourierNew'"&gt;"org.springframework.transaction.interceptor.TransactionProxyFactoryB<wbr>ean"</wbr></wbr></wbr></wbr>>

<wbr><wbr><wbr></wbr></wbr></wbr>"transactionManager">"transactionManager"><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>

<wbr><wbr><wbr></wbr></wbr></wbr>"transactionAttributes">

<wbr><wbr><wbr></wbr></wbr></wbr>

<wbr><wbr><wbr></wbr></wbr></wbr>"query*">PROPAGATION_REQUIRED,readOnly

<wbr><wbr><wbr></wbr></wbr></wbr>"get*">PROPAGATION_REQUIRED,readOnly

<wbr><wbr><wbr></wbr></wbr></wbr>"*">PROPAGATION_REQUIRED,-com.rubik.es.framework.exception.BaseAppException

<wbr><wbr><wbr></wbr></wbr></wbr>

<wbr><wbr></wbr></wbr>

<!—然后将每个业务接口将这个抽象Bean作为自己的父Bean,这样就继承下来了所有的属性-->

"IBasicManager" parent="txProxyTemplate">

<wbr><wbr><wbr><wbr><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr>"target">

<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>"com.rubik.es.logic.basic.impl.BasicManager">

<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>"commonDAO">"commonDAO"/>

<wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr><wbr><wbr><wbr></wbr></wbr></wbr>

<wbr><wbr><wbr><wbr><wbr><wbr></wbr></wbr></wbr></wbr></wbr></wbr>

<wbr><wbr></wbr></wbr>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值