终于搞清楚了,Java、Spring异常回滚和@Transactional加不加rollbackFor = Exception.class

先说结论:

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),就行了。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值