本来是在业务层已经使用了@Transaction注解,并且SpringBoot开启了事务管理器,但是下面的代码执行,还是不回滚,导致数据库进来了很多脏数据:
"transactionManager") (publicintcreateTest(NoteBookInfonoteBookInfo) throwsException { intret=noteBookInfoDaoImpl.create(noteBookInfo); if(ret==1){ thrownewException("rollback"); } return0; }
这里面有两个问题引起的,一个是对Spring的回滚异常不了解,一个是对Java的异常概念不了解,改成如下方式就可以了:
"transactionManager") (publicintcreateTest(NoteBookInfonoteBookInfo) throwsRuntimeException { intret=noteBookInfoDaoImpl.create(noteBookInfo); if(ret==1){ thrownewRuntimeException("rollback"); } return0; }
为什么RuntimeException可以,而Exception不可以,这里面主要是RuntimeException是unchecked类的,Exception不是unchecked的。而Spring的rollback要求的异常必须是unchecked。
/*** Defines zero (0) or more exception {@linkplain Class types}, which must be* subclasses of {@link Throwable}, indicating which exception types must cause* a transaction rollback.* <p>By default, a transaction will be rolled back on {@link RuntimeException}* and {@link Error} but not on checked exceptions (business exceptions). See* {@link org.springframework.transaction.interceptor.DefaultTransactionAttribute#rollbackOn(Throwable)}* for a detailed explanation.* <p>This is the preferred way to construct a rollback rule (in contrast to* {@link #rollbackForClassName}), matching the exception type and its subclasses* in a type-safe manner. See the {@linkplain Transactional class-level javadocs}* for further details on rollback rule semantics.* @see #rollbackForClassName* @see org.springframework.transaction.interceptor.RollbackRuleAttribute#RollbackRuleAttribute(Class)* @see org.springframework.transaction.interceptor.DefaultTransactionAttribute#rollbackOn(Throwable)*/Class<?extendsThrowable>[] rollbackFor() default {};
checked和unchecked的概念的区别简单的理解主要表现在编译器方面,编译器帮助你提示了就是checked的,比如FileNotFound,没提示的就是unchecked的,比如你代码跑起来以后,执行的时候报的NullPointException或者数组越界类的。JAVA的异常机制是一个大的体系,可以专门去学习了解。