AOP配置事务管理不生效

1、由于采用的是SpringMVC、MyBatis,故统一采用了注释来声明Service、Controller。由于服务器启动时的加载配置文件的顺序为web.xml---root-context.xml(Spring的配置文件)---servlet-context.xml(SpringMVC的配置文件),如果Controller在root-context.xml(Spring的配置文件)文件中扫描则Controller会先进行扫描装配,但是此时service还没有进行事务增强处理,得到的将是原样的Service(没有经过事务加强处理,故而没有事务处理能力),所以我们必须在root-context.xml(Spring的配置文件)中不扫描Controller,将Controller放在servlet-context.xml(SpringMVC的配置文件)中扫描。
事务的配置一般会在root-context.xml(Spring的配置文件)中配置或者Spring-Mybatis.xml中配置;Controller会放在servlet-context.xml(SpringMVC的配置文件)中扫描,如果Controller不放在servlet-context.xml(SpringMVC的配置文件)中扫描请求接口会报404;Service和Dao会放在root-context.xml(Spring的配置文件)中扫描。
2、如果你用了mysql数据库,需要(show engines;)查看数据库存储引擎是不是InnoDB,因为MyISAM是不支持事物的,如果不是需要改成InnoDB。
3、Spring AOP异常捕获原理:被拦截的方法需显式抛出异常,并不能经任何处理,这样AOP代理才能捕获到方法的异常,才能进行回滚,默认情况下AOP只捕获runtimeexception的异常,但可以通过配置来捕获特定的异常并回滚,换句话说在service的方法中不使用try catch 或者在catch中最后加上throw new runtimeexcetpion(),这样程序异常时才能被AOP捕获进而回滚。
解决方案:
方案1.例如service层处理事务,那么service中的方法中不做异常捕获,或者在catch语句中最后增加throw new RuntimeException()语句,以便让aop捕获异常再去回滚,并且在service上层(webservice客户端,view层action)要继续捕获这个异常并处理。
方案2.在service层方法的catch语句中增加:TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();语句,手动回滚,这样上层就无需去处理异常。
在service类前加上@Transactional,声明这个service所有方法需要事务管理。每一个业务方法开始时都会打开一个事务。Spring默认情况下会对运行期例外(RunTimeException)进行事务回滚。这个例外是unchecked;如果遇到checked意外就不回滚。
如何改变默认规则:
1)让checked例外也回滚:在整个方法前加上 @Transactional(rollbackFor=Exception.class)
2)让unchecked例外不回滚: @Transactional(notRollbackFor=RunTimeException.class)
3)不需要事务管理的(只查询的)方法:@Transactional(propagation=Propagation.NOT_SUPPORTED)
注意: 如果异常被try{}catch{}了,事务就不回滚了,如果想让事务回滚必须再往外抛try{}catch{throw Exception}。

附:execution表达式

<aop:config>
        <aop:pointcut id="pointcut" expression="execution(* com.loongshawn.method.ces..*.*(..))" />
        <aop:aspect ref="logAspect">
            <aop:before pointcut-ref="pointcut" method="beforeAdvice"/>
            <aop:after-returning pointcut-ref="pointcut" arg-names="joinPoint,retValue" returning="retValue" method="afterAdvice"/>
        </aop:aspect>
    </aop:config>

  上述配置为AOP配置代码片段,其中expression部分为定义切点的表达式部分,如下:

execution(* com.loongshawn.method.ces..*.*(..))

  注意:markdown中符号“*”是加粗,因此输出“*”符号需要进行转义“*”。

  表达式结构解释如下:

标识符含义
execution()表达式的主体
第一个“*”符号表示返回值的类型任意
com.loongshawn.method.cesAOP所切的服务的包名,即,需要进行横切的业务类
包名后面的“..”表示当前包及子包
第二个“*”表示类名,*即所有类
.*(..)表示任何方法名,括号表示参数,两个点表示任何参数类型

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值