@Transactional
这个注解相信大家都不陌生,这是事务的注解,什么是事务,无非就是未保证数据一致性,当出现任何异常时候出现数据回滚
注解是是不需要写提交事务的。
那么,最近我发现,这个@Transactional的注解,并不是所有异常都可以进行数据回滚,他只有是RuntimeException类及其子类(中文称为:运行时异常/unchecked异常/未检异常)异常的时候才会进行数据回滚,简单的说
@Override
@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);
}
以上这种情况由于:第十三行:bankCardMapper.add(bankCard);
因为上面出现异常插入失败了,是会出现数据回滚的,也就是 第五行:userMapper.add(user);
这段代码插入的user在数据库表中会失败,因为数据回滚了
但是当你这样写的时候,bankCardMapper.add(bankCard);会出现插入失败,但是userMapper.add(user);却插入进去了数据不会出现回滚,为什么呢,不是也一样声明了事务嘛,为何出现异常不会数据回滚
@Override
@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),就行了
@Override
@Transactional(rollbackFor = Exception.class)
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);
}