Spring @Transactional注解事务不生效

最近项目需要做一个功能,是给设备做签到功能的。相当于身份验证的东西,如果没有签到,就不能调用其他接口。项目原来的同事是先写一个验签方法,在需要验证签到的方法里面调用。这样一来就很麻烦,如果接口很多的话写起来真费劲。于是我就改成用AOP的方式处理。如下,定义一个切面

@Component
@Aspect
public class SignCheck {

    @Pointcut("execution(* com.api.web.ScialController.*(..)) " +
            "|| execution(* com.api.web.PaymentController.*(..))" +
            "|| execution(* com.api.web.BankController.*(..))" +
            "|| execution(* com.api.web.QueryControl.*(..))" +
            "|| execution(* com.api.web.SendMessageController.*(..))")
    public void chechSign() {}

    @Before("chechSign()")
    public void before(JoinPoint joinPoint) throws RestServiceException {
        Object[] args = joinPoint.getArgs();
        for (int i = 0; i < args.length; i++) {
            if (args[i] instanceof BaseRq) {
                BaseRq rq = (BaseRq) args[i];
                boolean result = SignUtil.validate(rq.getDeviceCode());
                if (!result) {
                    throw new RestServiceException("设备未签到");
                }
            }
        }
    }
}

其中 SignUtil.validate(rq.getDeviceCode())就是对设备进行验证签到的功能。这样一来ScialController,PaymentController等这几个类下的方法在执行之前便会去校验是否签到。

这里需要开启AOP,配置事务管理器。






    










    
    
    
    
    
    

为了校验事务是否生效,我在serviceA里面分别调用serviceB和serviceC的方法,BC在类上面添加@Transactional注解,A则是在方法上面加。相当于

@Transactional
public void A(){
    try {
        B();
        C();
        int i = 1/0;
    } catch (Exception e) {
        //打印日志
        throw new RestServiceException("系统错误");
    }
}

测试A()发现BC事务竟然不回滚。

后来查资料才发现catch里面抛出的RestServiceException继承Exception类,spring默认是不回滚的

Spring @Transactional注解事务不生效_第1张图片

解决方法就是,在注解添加rollbackFor属性,像这样就可以回滚了。

@Transactional(rollbackFor = Exception.class)
public void A(){
    try {
        B();
        C();
        int i = 1/0;
    } catch (Exception e) {
        //打印日志
        throw new RestServiceException("系统错误");
    }
}

 

你可能感兴趣的:(Java)