Spring、EJB的声明式事务默认情况下都是在抛出unchecked exception后才会触发事务的回滚
- /**
- * 如果在spring事务配置中不为切入点(如这里的切入点可以定义成test*)配置事务在什么情况下回滚(格式:-引起回滚的异常类型)
- * 则spring默认只会在service方法抛出unchecked exception才会触发回滚
- */
- public class TestServiceImpl extends Service implements TestService {
- /**
- * 测试spring异常触发事务回滚的service方法
- */
- public void testAddPerson(String name) throws Exception {
- TestPerson p = new TestPerson();
- p.setName(name);
- this.getHibernateGenericController().save(p);
- /*
- * 制造RuntimeException
- * 在spring默认的异常回滚策略下,该异常的抛出会触发事务的回滚,数据不会被插入
- */
- throw new RuntimeException("抛出个运行时异常");
- /**
- * 同样是unchecked exception,spring默认的异常回滚策略下Error的抛出也会触发事务的回滚,数据不会被插入
- */
- // throw new Error();
- /**
- * 即使是在spring默认的异常触发事务回滚策略(unchecked exception触发回滚)下,
- * 如果使用try-catch捕获抛出的unchecked异常后没有在catch块中采用页面硬编码的方式使用spring api对事务做显式的回滚,则事务不会回滚,数据被插入
- * “将异常捕获,并且在catch块中不对事务做显式提交=生吞掉异常”
- */
- // try {
- // throw new RuntimeException("这个抛出的运行时异常会被try-catch捕获");
- // } catch(Exception e) {
- // System.out.println("捕获到异常: " + e.getMessage());
- // }
- /**
- * 因为Exception类是个checked exception,所以这里抛出的异常不会触发事务的回滚,数据被插入
- */
- // throw new Exception("a Exception instance");
- /**
- * 该BaseException继承自Exception,也为checked exception,抛出它后:
- * spring默认的回滚策略下,事务未回滚, 数据被插入;
- * 在TransactionProxyFactoryBean的transactionAttributes中配置
- <prop key="test*">
- ... ...,-BaseException
- </prop>
- 后,事务回滚,数据未被插入
- */
- // throw new BaseException("一个BaseException");
- }
- }
spring默认对unchecked exception进行回滚。
也可以对规定的checked exception进行回滚:
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="get*" read-only="true" rollback-for="NoProductInStockException"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
将异常捕获,并且在catch块中不对事务做显式提交(或其他应该做的操作如关闭资源等)=生吞掉异常
spring的事务边界是在调用业务方法之前开始的,业务方法执行完毕之后来执行commit or rollback(Spring默认取决于是否抛出runtime异常).
如果抛出runtime exception 并在你的业务方法中没有catch到的话,事务会回滚。
一般不需要在业务方法中catch异常,如果非要catch,在做完你想做的工作后(比如关闭文件等)一定要抛出runtime exception,否则spring会将你的操作commit,这样就会产生脏数据.所以你的catch代码是画蛇添足。
Java 中定义了两类异常:
1) Checked exception: 这类异常都是Exception的子类 。异常的向上抛出机制进行处理,如果子类可能产生A异常,那么在父类中也必须throws A异常。可能导致的问题:代码效率低,耦合度过高。C#中就没有使用这种异常机制。
2) Unchecked exception: 这类异常都是RuntimeException的子类,虽然RuntimeException同样也是Exception的子类,但是它们是特殊的,它们不能通过client code来试图解决,所以称为Unchecked exception 。
checked exception是需要强制catch的异常,你在调用这个方法的时候,你如果不catch这个异常,那么编译器就会报错,比如说我们读写文件的时候会catch IOException,执行数据库操作会有SQLException等
UnChecked Exception是RuntimeException,也就是说运行时的异常,这种异常不是必须需要catch的,你是无法预料的,比如说你在调用一个list.szie()的时候,如果这个list为null,那么就会报NUllPointerException,而这个异常就是RuntimeException,也就是UnChecked Exception
Error和RuntimeException及其子类是unchecked exception.其他exception是checked exception.
checked exception可以出现在throws子句中,unchecked exception不可以。
Error是java自己的错误或者诸如内存耗尽等严重错误,是不可抗拒的,显然没有捕捉的必要,而且也没有办法捕捉。
RuntimeException是你的程序有逻辑错误,是程序员应该积极避免其出现的异常。比如NullPointerException等,完全是程序员马虎出的错。当遇到这种错误时,java将这个错误自动捕捉到,比如显示到concole里,然后继续运行。而checked exception如果不捕捉则会导致程序终止。
error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。
exception 表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况
error和excption的区别
Error的继承关系:
java.lang.Object
--java.lang.Throwable
--java.lang.Error
Exception的继承关系:
java.lang.Object
--java.lang.Throwable
--java.lang.Exception
二者的不同之处:
Exception:
1.可以是可被控制(checked) 或不可控制的(unchecked)
2.表示一个由程序员导致的错误
3.应该在应用程序级被处理
Error:
1.总是不可控制的(unchecked)
2.经常用来用于表示系统错误或低层资源的错误
3.如何可能的话,应该在系统级被捕捉