spring中事务和aop的顺序问题二(配置形式)

来源:互联网 发布:淘宝网舞鞋 编辑:程序博客网 时间:2024/06/10 05:27

今 天在开发过程中发现一个很奇怪的问题,在模拟事务回滚过程中,发现事务回滚没问题,异常也输出了,但之前配置的afterthrowing记录出错日志配 置却始终不好用,根本不会执行到afterthrowing配置的方法内但afterreturning配置 却没有问题,去掉配置的AOP事务后,afterthrowing一切正常。。。仔细想想整个程序执行步骤,考虑到事务的回滚用到的是环绕通知 around,是不是两个同时执行,log拦截器包含在了事务拦截器里,所以当事务遇到了错误回滚也直接将插入异常日志一同回滚了?能不能在事务执行遇到 exception回滚以后再去控制它去进入afterthowing配置的方法?于是我又仔细看了看spring 关于aop的配置,惊喜的发现一个"order"参数,这个参数是用来控制aop通知的优先级,值越小,优先级越高,于是我手动设置了事务与异常日志两个 aop通知的order 参数,控制log拦截器在事务的around之外,不出我所料,问题最终得到解决~~

以下是部分代码,可供参考:

<!-- AOP 事务 -->   <aop:config>        <aop:pointcut id="serviceMethods"            expression="execution(* hamob.*.*(..))" />        <aop:advisor advice-ref="txAdvice"            pointcut-ref="serviceMethods" order="2"/>    </aop:config>    <tx:advice id="txAdvice" transaction-manager="transactionManager">        <tx:attributes>            <tx:method name="save*" propagation="REQUIRED" isolation="READ_COMMITTED"/>         <tx:method name="add*" propagation="REQUIRED" isolation="READ_COMMITTED"/>         <tx:method name="update*" propagation="REQUIRED" isolation="READ_COMMITTED"/>         <tx:method name="delete*" propagation="REQUIRED" isolation="READ_COMMITTED"/>            <tx:method name="*"/>        </tx:attributes>    </tx:advice><!-- AOP 日志管理 -->    <aop:config>        <aop:aspect ref="logadvice" order="3">            <aop:pointcut id="logInsertMethods" expression="execution(* hamob.*.save*(..))"/>            <aop:after-returning method="saveLog" pointcut-ref="logInsertMethods" returning="rvt"/>        </aop:aspect>    </aop:config>    <!-- AOP throwing管理 -->    <aop:config>        <aop:aspect ref="logadvice" order="1">            <aop:pointcut id="throwinglog" expression="execution(* hamob.*.save*(..))"/>            <aop:after-throwing pointcut-ref="throwinglog" throwing="throwable" method="afterThrowing"/>        </aop:aspect>    </aop:config>

在我的程序中,由于用到了hibernate,因此事务注解分布在各处,结果发现after-throwing无法抓取异常(在指定包名后)。在一个数据库操作抛出异常后,事务管理器采取了回滚策略,导致程序抛出异常后,回滚到事务管理器的处理中,指定包名后更加抓取不到异常了。

<aop:config>        <aop:aspect ref="exceptionCacher" order="0">        <aop:pointcut id="performance2" expression="execution(* com.ebupt.justholdon.server..*.*(..))" />        <aop:after-throwing pointcut-ref="performance2" method="throwExp"  throwing="exp"/>        </aop:aspect> </aop:config> 


0 0