一般来说,我们百度的时候, 配置 基于注解的声明式事务注解一般是

<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />

其实是没有错的,但是 这样是不全,很可能 会使 事务 没起效果的。

由于采用的是SpringMVC、 MyBatis,故统一采用了标注来声明Service、Controller 由于服务器启动时的加载配置文件的顺序为web.xml---root-context.xml(Spring的配置文件)---servlet-context.xml(SpringMVC的配置文件),由于  

root-context.xml配置文件中Controller会先进行扫描装配,但是此时service还没有进行事务增强处理,得到的将是原样的Service(没有经过事务加强处理,故而没有事务处理能力),所以我们必须在root-context.xml中不扫描Controller,配置如下:  

 

<!-- 自动扫描组件,这里要把controler下面的 controller去除,他们是在spring3-servlet.xml中配置的,如果不去除会影响事务管理的。   -->  
     <context:component-scan base-package="com.sence">  
          <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />   
     </context:component-scan>
在servlet-context.xml中扫描Controller同时不扫描Service,配置如下:
<!-- 扫描所有的controller 但是不扫描service-->  
    <context:component-scan base-package="com.sence">  
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />  
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" />  
    </context:component-scan>

原作者说他测试过了,如果 扫描的时候 不 进行 对应的包扫描的配置, 注解事务,也是没有起到回滚的 作用的。 需要加上 包的扫描的配置的。

以上都加上了,那么有一个问题了。 如果 我们 使用 基于 xml 的 aop 的事务配置了之后, 那么又在 方法或者 类上使用了事务注解, 哪个优先级更高 ?原作者的测试结果是 : 事务注解的优先级更高 。 如果由于自定义的AOP ,产生异常的时候,可能会使事务注解没有产生回滚,或者造成影响。 百度的结果是 : 配置事务注解的优先级,默认是优先级最低的。

<!-- 开启事务控制的注解支持,proxy-target-class="true"类代理适用范围广  -->
     <!-- order 一般是不用配置的,如果aop xml 配置了事务了,代码又使用了事务的注解,那么以代码的注解为主。
     带上order 是防止以后代码上有其他自定义的AOP 而影响了事务注解的aop的异常的事务回滚,默认事务注解的aop的优先级最低。
     加上也是为了明确告诉spirng 声明式事务注解优先级最高。
       -->  
    <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" order="200"/>

注解用法:

@Transactional 可以作用于接口、接口方法、类以及类方法上。当作用于类上时,该类的所有 public 方法将都具有该类型的事务属性,同时,我们也可以在方法级别使用该标注来覆盖类级别的定义。

虽然 @Transactional 注解可以作用于接口、接口方法、类以及类方法上,但是 Spring 建议不要在接口或者接口方法上使用该注解,因为这只有在使用基于接口的代理时它才会生效。另外, @Transactional 注解应该只被应用到 public 方法上,这是由 Spring AOP 的本质决定的。如果你在 protected、private 或者默认可见性的方法上使用 @Transactional 注解,这将被忽略,也不会抛出任何异常。

默认情况下,只有来自外部的方法调用才会被AOP代理捕获,也就是,类内部方法调用本类内部的其他方法并不会引起事务行为,即使被调用方法使用@Transactional注解进行修饰。