一、先看栗子:
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = { RuntimeException.class, Error.class,
Exception.class })
@Override
public void test1() throws Exception {
for (long i = 0; i < 2; i++) {
insert(i);
}
arService.test1();
// throw new RuntimeException("aa");
throw new IOException("aa");
}
arService:
@Transactional
public void test1() throws Exception {
for (long i = 0; i < 2; i++) {
insert(i);
}
// ok,全部回滚
// throw new RuntimeException("aa");
// ok,全部回滚
//throw new IOException("aa");
}
以上事务可以正常回滚。
那么问题来了:
1。上面为什么加rollbackFor呢?
Open Declaration Class<? extends Throwable>[] org.springframework.transaction.annotation.Transactional.rollbackFor() : {}
Defines zero (0) or more exception classes, which must besubclasses of Throwable, indicating which exception types must causea transaction rollback.
By default, a transaction will be rolling back on RuntimeException and Error but not on checked exceptions (business exceptions). See org.springframework.transaction.interceptor.DefaultTransactionAttribute.rollbackOn(Throwable)for a detailed explanation.
This is the preferred way to construct a rollback rule (in contrast to rollbackForClassName), matching the exception class and its subclasses.
Similar to org.springframework.transaction.interceptor.RollbackRuleAttribute.RollbackRuleAttribute(Class clazz).
See Also:rollbackForClassNameorg.springframework.transaction.interceptor.DefaultTransactionAttribute.rollbackOn(Throwable)
相信都能看懂了吧。默认情况下事务只回滚RuntimeException and Error两种异常,IOException异常不能回滚,因为IOException是非运行时异常。如下图:
2。注意两点:
1)。执行过程中的 runtime exception 会由 spring 捕获,并回滚之前执行的 sql
2)。在 Transactional 内部,不要 try catch,事务才能生效。
二、再看栗子:
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = { RuntimeException.class, Error.class,
Exception.class })
@Override
public void test1() throws Exception {
for (long i = 0; i < 2; i++) {
insert(i);
}
ApplicationContextUtil.getBean(this.getClass()).test3();
// throw new BusinessException("aa");
throw new IOException("aa");
}
@Transactional
public void test3() throws Exception {
insert();
}
是不是发现调用test3方法有点特别?
在spring 中使用 @Transactional 、 @Cacheable 或 自定义 AOP 注解时,会发现个问题:在对象内部的方法中调用该对象的其他使用AOP注解的方法,被调用方法的AOP注解失效。