先说结论:
1、加上没有错。@Transactional(rollbackFor = Exception.class)
2、有spring的情况下SQLException,被包装为RuntimeException。
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
3、Error必回滚。
4、RuntimeException必回滚。
5、Exception下的RuntimeException会回滚,checkException不回滚
6、checkException需要@Transactional(rollbackFor = Exception.class)。
throwable是所有异常的根,java.lang.Throwable
Error是错误,java.lang.Error
Exception是异常,java.lang.Exception
Exception:一般分为Checked异常和Runtime异常,所有RuntimeException类及其子类的实例被称为Runtime异常,不属于该范畴的异常则被称为CheckedException。
我们比较熟悉的RumtimeException类的子类有
Java.lang.ArithmeticException
Java.lang.ArrayStoreExcetpion
Java.lang.ClassCastException
Java.lang.IndexOutOfBoundsException
Java.lang.NullPointerException
我们比较熟悉的Checked异常有
Java.lang.ClassNotFoundException
Java.lang.NoSuchMetodException
java.io.IOException
2 Springboot中声明事务@Transactional,有时候声明了事务报异常数据却不会回滚
@Transactional注解只有抛出RuntimeException类及其子类异常(中文称为:运行时异常/unchecked异常/未检异常)才能回滚,其他的所有异常都不行
----会回滚—RuntimeException
@Transactional
public void register(User user, BankCard bankCard){
//插入一条数据
userMapper.add(user);
try {
int value = 5 / 0;
}catch (RuntimeException e){
throw new RuntimeException("抛异常了");
}
//插入另一条数据
bankCard.setUserId(user.getId());
bankCardMapper.add(bankCard);
----不会回滚----Exception
@Transactional
public void register(User user, BankCard bankCard) throws Exception{
//插入一条数据
userMapper.add(user);
try {
int value = 5 / 0;
}catch (Exception e){
throw new Exception("抛异常了");
}
//插入另一条数据
bankCard.setUserId(user.getId());
bankCardMapper.add(bankCard);
那是因为@Transactional这个注解只会在RuntimeException(运行时异常),这种异常时才会进行数据回滚,而Exception(受检异常)抛出的时候,是不会进行数据回滚的,这个时候我们想他报Exception异常的时候依旧想他进行数据回滚要怎么办。只需要在@Transactional后面加上(rollbackFor = Exception.class),就行了。