单一架构中Spring手动或自动抛出异常时,既要要返回错误信息,还要做事务回滚

情况一:代码出现异常

@Override
    @Transactional(rollbackFor = Exception.class)
    public RspMessage add() {
        Inventory inventory = new Inventory();
        inventory.setGoodsId(2);
        inventory.setGoodsNumber(11);
        inventory.setCreateTime(new Date());
        inventory.setStatus(0);
        inventoryDao.insert(inventory);//新增数据
        String st = "adafasd";
        Integer.parseInt(st);//这里会出现异常
        return new RspSuccessMessage();
    }

出现异常时,这里会对新增数据时,进行异常回滚,但是如果没有做全局异常捕获,这里是会返回异常,不会返回自定义的错误码的。

情况二:代码出现异常

@Override
    @Transactional(rollbackFor = Exception.class)
    public RspMessage add() {
        try{
            Inventory inventory = new Inventory();
            inventory.setGoodsId(2);
            inventory.setGoodsNumber(11);
            inventory.setCreateTime(new Date());
            inventory.setStatus(0);
            inventoryDao.insert(inventory);//新增数据
            String st = "adafasd";
            Integer.parseInt(st);//这里会报异常
        }catch (Exception e){
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//手动回滚事务
            return new RspFailMessage("","保存错误:"+e.getMessage());//自定义的返回信息
        }
        return new RspSuccessMessage();
    }

如果这里不加上:

TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//手动回滚事务

那么这里捕获了异常,事务也不会回滚的。

建议使用)情况三:手动抛出异常,假如:一个方法需要对3个数据表进行修改,但是其中前面的2个表修改成功了,但是第3个表失败了,那么这里就要手动抛出事务,对前面2个表就行事务回滚。

    @Override
    @Transactional(rollbackFor = Exception.class)
    public RspMessage add() {
        try{
            Inventory inventory = new Inventory();
            inventory.setGoodsId(3);
            inventory.setGoodsNumber(11);
            inventory.setCreateTime(new Date());
            inventory.setStatus(0);
            int i = inventoryDao.insert(inventory);
            if (i == 0){
                //这里是我自定义的异常,专门用来判断是否满足业务条件的,
                // 比如:有两个保存,第一个新增执行完成了,但是第二个新增没有保存成功,但是也没有报异常,这个时候,就需要手动抛出异常,让第一个新增回滚
                throw new DissatisfyConditionException("保存失败");//手动抛出异常
            }
        }catch (Exception e){
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//手动回滚事务
            return new RspFailMessage("","保存错误:"+e.getMessage());//返回自定义的信息
        }
        return new RspSuccessMessage();
    }

上面的情况二、情况三;都是使用的 try catch 捕获异常,如果是捕获异常,必须要要加上哪一串代码的,才可以进行事务回滚,如果使用抛出异常,那么必须要写一个全局的异常捕获来处理异常了,不然使用抛出异常,是返回不了自定义的信息的。

自定义异常:

/**
 * 自定义异常,用于抛出 业务中不满足继续执行下去的条件的异常
 */
public class DissatisfyConditionException extends Exception {

    // 提供一个有参数的构造方法,可自动生成
    public DissatisfyConditionException(String message) {
        super(message);// 把参数传递给Throwable的带String参数的构造方法
    }
}

spring boot的全局异常捕获:

import com.qw.utils.RspFailMessage;
import com.qw.utils.RspMessage;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolationException;
import java.util.Map;

import static java.util.stream.Collectors.toMap;

/**
 * 全局异常捕获
 */
@RestControllerAdvice
public class GlobalExceptionHandle {

    /**
     * 用于 Spring validation后台校验框架 中实体类的注解验证的错误
     * @param e
     * @return
     */
    @ExceptionHandler(value = BindException.class)//value : 需要捕获的异常,可以填写多个。
    public RspMessage modelFieldEmptyException(BindException e) {
        Map<String, Object> errors = e.getBindingResult().getFieldErrors().stream().collect(toMap(FieldError::getField, FieldError::getDefaultMessage));
        return new RspFailMessage(errors);//返回的自定义信息
    }

    /**
     * 捕获自定义的异常,这个异常是业务层中不满足条件的异常。
     * @param e
     * @return
     */
    @ExceptionHandler(value = DissatisfyConditionException.class)
    public RspFailMessage modelFieldEmptyException(DissatisfyConditionException e) {
        return new RspFailMessage(e.getMessage());//返回的自定义信息
    }
}

 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值