JAVA-AOP对存储过程事务进行回滚操作

编写要监控的注解

package io.hk.common.annotation;

import java.lang.annotation.*;

@Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TransactionAnnotation {
}

AOP切面

package io.hk.common.aspect;


import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.util.Map;


@Aspect
@Component
public class TransactionAspect {

   @Resource
   private TransactionAspectSupport transactionAspectSupport;

    public TransactionAspect() {
    }

    @Pointcut("@within(io.hk.common.annotation.TransactionAnnotation) || @annotation(io.hk.common.annotation.TransactionAnnotation)")
    public void addPointCut() {
    }

    @Around("addPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        Object result = point.proceed();
        TransactionStatus transactionStatus = TransactionAspectSupport.currentTransactionStatus();
        // 如果存在事务且运行失败,则回滚
        String code = ((Map)result).get("code").toString();
        if ("1".equals(code)) {
            // 手动回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return result;
    }
}

把注解放到要回滚的方法上

QA:

为什么新建一个新的事务(采用Propagation.REQUIRES_NEW的事务传播机制)???

手动回滚事务以后无法返回错误信息到前台(直接返回500)

Spring 源码分析:

 

 

 

采用Propagation.REQUIRES_NEW的事务传播机制,在serviceImpl层,每次都新生成一个事务

 

如果code != 0会把这个新事物回滚,程序也会继续执行下去。不会影响到把错误信息返回到前台(不会报上次看到的500问题)

实现事务的回滚 也保证了原子性

posted @ 2024-10-15 13:31  skystrivegao  阅读(54)  评论(0)    收藏  举报