工作中因为事务回滚的问题,搞了一下午,Spring的各种方式都尝试了都不起作用,最后发现是我最初配置事务的AOP扫描路径错了(最初使用的是在xml中配置事务,使用AOP切面方式实现事务回滚的)
Spring的三种事务回滚方式
1.@Transactional注解
这种方式在需要的地方添加该注解即可
@Transactional(rollbackFor = Exception.class)
@Override
public void insertTest() {
//SQL执行逻辑
insert1();
insert2();//insert2数据库中出错,insert1回滚
}
@Transactional(rollbackFor = Exception.class)
@Override
public void insertTest() {
try {
insert1();
insert2();//insert2数据库中出错,insert1回滚
} catch (Exception e) {
e.printStackTrace();
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//就是这一句了,加上之后,如果insert2()抛了异常,//insert1()是会回滚的
}
2.在xml中配置事务
在xml中配置好,代码中无需再写,代码整洁,xml的配置内容如下
<!-- 事务管理器配置 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 传播行为 -->
<tx:method name="save*" propagation="REQUIRED" />
<tx:method name="insert*" propagation="REQUIRED" />
<tx:method name="delete*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="query*" propagation="SUPPORTS" read-only="true" />
<tx:method name="select*" propagation="SUPPORTS" read-only="true" />
<tx:method name="get*" propagation="SUPPORTS" read-only="true" />
</tx:attributes>
</tx:advice>
<!-- 切面 配置需要回滚的业务层包路径 -->
<aop:config>
<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.priv.test.service..*.*(..))" />
</aop:config>
<!-- 配置日志拦截器 -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
3.手动回滚
即在代码中手动抛出RuntimeException异常,如下所示:
注意,这里必须是重新抛出,让spring来处理,不然是不会rollback的
try{
//SQL执行逻辑
insert1();
insert2();//insert2数据库中出错,insert1回滚
}catch (Exception e){
throw new RuntimeException(e);//注意,这里必须是重新抛出,让spring来处理,不然是不会rollback的
}
事务回滚时只会对RuntimeException(Unchecked 非受检异常)回滚
RuntimeException所包含的子类具体如下所示
RuntimeException子类 | 异常说明 |
---|---|
NullPointerException | 操作对象为Null |
NumberFormatException | 字符串转化成数字 |
IllegalArgumentException | 传递了不合法的参数 |
ArithmeticException | 零作为除数等 |
UnsupportedOperationException | 该操作不支持 |
ClassCastException | 类型转换 |
ArrayIndexOutOfBoundsException | 数组越界 |
StringIndexOutOfBoundsException | 字符串越界 |
NestedRuntimeException | 嵌套的运行时异常 |
平常运行时经常遇到的那些异常,都是RuntimeException的子类