您的位置:首页 > 编程语言 > Java开发

Spring transaction事务之roll back回滚: rollback-for

2017-04-21 10:58 351 查看
试验方法:

写一个单元测试,调用一个service层方法(发生对数据库进行写操作的方法–insert、update、delete)即可.

applicationContext.xml 样子(如何设置rollback-for)

<!–

spring事务管理 方法一–>

<bean id="transactionManager"

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

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

</bean>

<aop:config>

<aop:pointcut id="serviceOperation" expression="execution(*

com.*.service.*.*(..))" />

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

</aop:config>

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

<tx:attributes>

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

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

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

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

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

</tx:attributes>

</tx:advice>

试验过程:

定义一个service方法如下:

public SMSTiming createSMSTiming(SMSTiming smsTiming){

SMSTiming s= this.getSmsTimingDAO().createSMSTiming(smsTiming);

return s;

}

定义二个异常(先默认配置TestException为Spring事务回滚异常):

publicclass MyTestException extends Exception

publicclass TestException extends Exception

nbsp; 注意看下:每次这个方法的不同处(抛出的异常不同)。



测试1:

public SMSTiming createSMSTiming(SMSTiming smsTiming){

SMSTiming s= this.getSmsTimingDAO().createSMSTiming(smsTiming);

int i = 4/0; //人为产生异常(实际这里抛出了ArithmeticException运行异常)

return s;

}

测试1结果:会事务回滚—-数据库中未插入新数据。

测试2:

public SMSTiming createSMSTiming(SMSTiming smsTiming) throws Exception{//受检异常(非运行异常)必须抛出

SMSTiming s= this.getSmsTimingDAO().createSMSTiming(smsTiming);

try{

int i = 4/0; //人为产生异常

}catch(Exception e){

thrownew Exception ("");//抛出Exception异常

}

return s;

}

测试2结果:不会事务回滚—-数据库中插入新数据。

测试3:

public SMSTiming createSMSTiming(SMSTiming smsTiming) throws RuntimeException{//运行异常(非受检异常)可以不抛出

SMSTiming s= this.getSmsTimingDAO().createSMSTiming(smsTiming);

try{

int i = 4/0; //人为产生异常

}catch(Exception e){

thrownewRuntimeException("");//抛出RuntimeException异常

}

return s;

}

测试3结果:会事务回滚—-数据库中未插入新数据

测试4:

public SMSTiming createSMSTiming(SMSTiming smsTiming) throws TestException{//受检异常(非运行异常)必须抛出

SMSTiming s= this.getSmsTimingDAO().createSMSTiming(smsTiming);

try{

int i = 4/0; //人为产生异常

}catch(Exception e){

thrownewTestException("");//抛出TestException异常

}

return s;

}

测试4结果:会事务回滚—-数据库中未插入新数据。

测试5:

public SMSTiming createSMSTiming(SMSTiming smsTiming) throws MyTestException{//受检异常(非运行异常)必须抛出

SMSTiming s= this.getSmsTimingDAO().createSMSTiming(smsTiming);

try{

int i = 4/0; //人为产生异常

}catch(Exception e){

thrownewMyTestException("");//抛出MyTestException异常

}

return s;

}

测试5结果:不会事务回滚—-数据库中插入新数据。

测试6:

public SMSTiming createSMSTiming(SMSTiming smsTiming) throws MyTestException{//受检异常(非运行异常)必须抛出 (注意:此时spring指定配置此异常回滚)

SMSTiming s= this.getSmsTimingDAO().createSMSTiming(smsTiming);

try{

int i = 4/0; //人为产生异常

}catch(Exception e){

thrownewMyTestException("");//抛出MyTestException异常

}

return s;

}

测试6结果:会事务回滚—-数据库中未插入新数据。

试验总结:

测试1、测试3、测试4、测试6会进行事务回滚;测试2、测试5不会进行事务回滚。

为什么会这样?因为是异常的类型(受检异常、运行时异常)不同或使用了Spring的rollback-for配置。

测试1和测试3是因为抛出了运行时异常,会事务回滚。

测试4和测试5、测试6分别抛出受检异常TestException、MyTestException,那为什么测试4和测试6会事务回滚呢?

因为是我们在Spring事务配置中指定了此异常(指定rollback-for)。

又一篇文章:

昨天同事说Spring的Transactional必须添加rollbackFor = Exception.class,否则事务不会回滚。但我原来试过,抛出RuntimeException时是会回滚的。于是查看Spring的Transactional的API文档,发现下面这段:

If no rules are relevant to the exception, it will be treated like
DefaultTransactionAttribute
(rolling
back on runtime exceptions).

后面又试了下发现,如果不添加rollbackFor等属性,Spring碰到Unchecked Exceptions都会回滚,不仅是RuntimeException,也包括Error。

转载地址
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: