我们上一篇说到,只有 java .lang.RuntimeException和Error异常才会被spring事务捕捉并回滚,但Java.lang.SQLExcepetion是Java.lang.Excepetion的子类,在没有对事务设置rollbackfor=Exception.class时是不会默认对捕获的该类型异常触发事务回滚操作,而实际情况却与此相反,触发了事务回滚,这是怎么回事呢?
对此,我们先找一个sql运行的异常信息,如下:
[Request processing failed; nested exception is org.springframework. dao .DuplicateKeyException:
### Error updating database. Cause: com. mysql . jdbc .exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry ‘1’ for key 1
可以发现其抛出的是org.springframework.dao.DuplicateKeyException,是一个框架自定义的sql异常,我们知道 org.springframework.dao.DuplicateKeyException来自spring-tx-4.0.0.RELEASE.jar
反编译 可见:
java.lang.Object
|____java.lang.Throwable
|____ java.lang.Exception
|____ java.lang.RuntimeException
|____ org.springframework.core.NestedRuntimeException
|____org.springframework.dao.DataAccessException
|____ org.springframework.dao.NonTransientDataAccessException
|____org.springframework.dao.DataIntegrityViolationException
|____org.springframework.dao.DuplicateKeyException
同样方法可以查得:org.springframework.dao中的异常都是RuntimeException的子类。
结论:Spring框架下,所有SQL异常都被org.springframework重写为RuntimeException的子类,所以事务因此也会发生回滚!