天天看点

Spring事务管理之回滚异常rollback-for

一、业务背景

业务需求:服务层调用多个dao方法,要求只要有一条数据库执行语句出错,则全部回滚。而实际情况是前面四条执行成功,第五条失败,结果只是抛出异常提示,前面四条还是成功执行。

二、出错原因

异常分为checked Exception 捕获异常 跟 unchecked Exception 未捕获异常,Spring默认发生未捕获异常时自动回滚,如发生RuntimeException。项目中都有针对调用dao层方法做try-catch处理,即已经对异常做出捕获处理,不满足Spring默认自动回滚情况,所以才会出现上面所述情况。

三、解决方案(两种)

如果想要不管有没有捕获异常做处理,只要其中一条发生异常,则全部回滚,那么可以采用下面两种配置方法:

1、xml文件中进行显示配置

        <!-- 事务配置 -->

<bean id="transactionManager"

class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

<property name="dataSource" ref="dataSource" />

</bean>

<!-- 增加事务回滚切面扫描配置,不加的话有捕获异常就不回滚 -->

<aop:config>

<aop:pointcut id="serviceOperation" expression="execution(* com.abc.service..*.*(..))"/>

<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceOperation"/>

</aop:config>

<!--事务管理,ServiceException事务回滚-->

<tx:advice id="txAdvice" transaction-manager="transactionManager">

<tx:attributes>

<tx:method name="get*" read-only="true" />

<tx:method name="query*" read-only="true" />

<tx:method name="find*" read-only="true" />

<tx:method name="load*" read-only="true" />

<tx:method name="select*" read-only="true" />

<tx:method name="*" rollback-for="Exception" />

</tx:attributes>

</tx:advice>

其中execution(* com.abc.service..*.*(..))表示:service包和所有子包里的任意类的任意方法。当然数据源记得配置,注解驱动及service类上加@Transactional可有可无。

2、采用注解@Transactional

配置@Transactional注解的rollbackFor属性,即在每个需要回滚的service类上加@Transactional(rollbackFor = Exception.class),代替xml的切面配置及事务管理

继续阅读