读书人

spring 引语事务

发布时间: 2012-09-10 22:20:12 作者: rapoo

spring 注解事务



方法的可见度和 @Transactional

在使用代理的时候,@Transactional 注解应该只被应用到 public 可见度的方法上。 如果你在 protected、private 或者 package-visible 的方法上使用 @Transactional 注解,系统也不会报错, 但是这个被注解的方法将不会执行已配置的事务设置。如果你非要注解非公共方法的话,请参考使用AspectJ


<tx:annotation-driven/> 设置

属性 默认值 描述
transaction-manager transactionManager 使用的事务管理器的名字。只有像在上面的例子那样,事务管理器不是 transactionManager的情况下才需要。

mode proxy 默认的模式“proxy”会用Spring的AOP框架来代理注解过的bean(就像在前面讨论过的那样, 下面代理的语义只对通过代理传递过来的方法调用起效)。 另一种可行的模式"aspectj"会使用Spring的AspectJ事务切面来编织类(通过修改目标对象的字节码应用到任何方法调用上)。 AspectJ织入需要在classpath中有spring-aspects.jar这个文件,并且启用装载时织入 (或者编译时织入)。

proxy-target-class false 只对代理模式有效。决定为那些使用了@Transactional注解的类创建何种事务代理。 如果 "proxy-target-class" 属性被设为 "true", 那么基于类的代理就会被创建。如果 "proxy-target-class"属性被设为"false" 或者没设,那么基于接口的标准JDK代理就会被创建。

order Ordered.LOWEST_PRECEDENCE 定义事务通知的顺序会作用到使用@Transactional注解的bean上。 更多的关于AOP通知顺序的定义可以在章节 请注意如果不指定任何顺序将会把决定权交给AOP子系统。




注意
在<tx:annotation-driven/>元素上的"proxy-target-class" 属性 控制了有什么类型的事务性代理会为使用@Transactional 来注解的类创建代理。 如果"proxy-target-class" 属性被设为"true",那么基于类的代理就会被创建。 如果"proxy-target-class" 属性被设为"false" 或者没设,那么会创建基于接口的标准JDK代理。

在多数情形下,方法的事务设置将被优先执行。在下列情况下,例如: DefaultFooService 类在类的级别上被注解为只读事务,但是,这个类中的 updateFoo(Foo) 方法的 @Transactional 注解的事务设置将优先于类级别注解的事务设置。


上面配置的结果将获得到一个拥有剖析和事务方面的 按那样的顺序 应用于它上面的 'fooService' bean。 许多附加的方面的配置将一起达到这样的效果。

最后,下面的一些示例演示了使用纯XML声明的方法来达到上面一样的设置效果。


上面配置的结果是创建了一个 'fooService' bean,剖析方面和事务方面被 依照顺序 施加其上。如果我们希望剖析通知在目标方法执行之前 后于 事务通知执行,而且在目标方法执行之后 先于 事务通知,我们可以简单地交换两个通知bean的order值。

如果配置中包含更多的方面,它们将以同样的方式受到影响。

结合AspectJ使用 @Transactional
通过AspectJ切面,你也可以在Spring容器之外使用Spring框架的 @Transactional 功能。要使用这项功能你必须先给相应的类和方法加上 @Transactional注解,然后把 spring-aspects.jar 文件中定义的 org.springframework.transaction.aspectj.AnnotationTransactionAspect 切面连接进(织入)你的应用。同样,该切面必须配置一个事务管理器。你当然可以通过Spring框架容器来处理注入,但因为我们这里关注于在Spring容器之外运行应用,我们将向你展示如何通过手动书写代码来完成。


// construct an appropriate transaction manager
DataSourceTransactionManager txManager = new DataSourceTransactionManager(getDataSource());

// configure the AnnotationTransactionAspect to use it; this must be done before executing any transactional methods
AnnotationTransactionAspect.aspectOf().setTransactionManager(txManager);
注意
使用此切面(aspect),你必须在 实现 类(和/或类里的方法)、而 不是 类的任何所实现的接口上面进行注解。AspectJ遵循Java的接口上的注解 不被继承 的规则。

定义在类上的 @Transactional 注解指定了类中所有方法执行时的默认事务语义。

定义在类的方法上的 @Transactional 注解将覆盖掉类上注解的所指定的默认事务语义(如过存在的话)。 所有的方法都可以注解,不管它的可见度是什么样的。

要把 AnnotationTransactionAspect 织入你的应用,你或者基于AspectJ构建你的应用

读书人网 >编程

热点推荐