排查
- 查看数据库或表,设置的引擎。MyISAM是不支持事务的,必须改为InnoDb。
- @Transactional注解的方法是否为public。
如果应用在protected、private或者 package的方法上,不会报错,但是事务设置不会起作用。 - @Transactional所注解的方法所在的类,是否已经使用了注解@Service或@Component等。
- 需要调用该方法,且需要支持事务特性的调用方,是在 @Transactional所在的类的外面。
注意:类内部的其他方法调用这个注解了@Transactional的方法,事务是不会起作用的。 - 注解为事务范围的方法中,事务的回滚仅仅对于unchecked的异常有效。对于checked异常无效。也就是说事务回滚仅仅发生在
出现RuntimeException或Error的时候。
解决方案
1.手动回滚。给service层方法注解加上参数:@Transactional(rollbackFor=Exception.class)
,方法上声明抛出RuntimeException异常,去除方法内的try catch,在控制层处理异常信息,进行try catch异常捕获处理。
2. 如上述分析。对uncheck异常进行catch,然后抛出RuntimeException异常。
3. 在service层方法的catch语句中增加:TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
语句,手动回滚,这样上层就无需去处理异常。