手写Spring事务注解核心逻辑

@Transactional 等价于 编程式事务逻辑 + AOP + 底层数据源

核心类与核心执行逻辑 

第一版

自定义事务注解

import org.springframework.core.annotation.AliasFor;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;

import java.lang.annotation.*;

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface MyTransactional {

    @AliasFor("transactionManager")
    String value() default "";

    @AliasFor("value")
    String transactionManager() default "";

    String[] label() default {};
    
    Propagation propagation() default Propagation.REQUIRED;


    Isolation isolation() default Isolation.DEFAULT;

    int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;

    String timeoutString() default "";

    boolean readOnly() default false;

    Class<? extends Throwable>[] rollbackFor() default {};

    String[] rollbackForClassName() default {};

    Class<? extends Throwable>[] noRollbackFor() default {};

    String[] noRollbackForClassName() default {};
}
import com.gary.demo.transaction.MyTransactionStatus;
import com.gary.demo.transaction.TransactionUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Component
public class MyTransactionInterceptor {

    // 全局接受事务状态
    private MyTransactionStatus transactionStatus;
    @Autowired
    private TransactionUtil transactionUtil;

    /**
     * 环绕通知 在方法之前和之后处理事情
     *
     * @param pjp 切入点
     */
    @Around("execution(* com.gary.demo.service.*.*(..))")
    public void around(ProceedingJoinPoint pjp) throws Throwable {
        // 1.获取方法的注解
        MyTransactional annotation = this.getMyTransactional(pjp);
        // 2.判断是否需要开启事务
        begin(annotation);
        // 3.调用目标代理对象方法
        pjp.proceed();
        // 4.判断关闭事务
        commit();
    }

    /**
     * 开启事务
     */
    private void begin(MyTransactional annotation) {
        System.out.println("[开启事务]===========>" + annotation.value());
        transactionStatus = transactionUtil.begin();
    }

    /**
     * 关闭事务
     */
    private void commit() {
        System.out.println("[关闭事务]===========>");
        transactionUtil.commit(transactionStatus);
    }

    /**
     * 获取代理方法上的事务注解
     *
     * @param pjp 切入点
     */
    private MyTransactional getMyTransactional(ProceedingJoinPoint pjp) throws Exception {
        //1. 获取代理对对象的方法
        String methodName = pjp.getSignature().getName();
        //2. 获取目标对象
        Class<?> classTarget = pjp.getTarget().getClass();
        //3. 获取目标对象类型
        Class<?>[] par = ((MethodSignature) pjp.getSignature()).getParameterTypes();
        //4. 获取目标对象方法
        Method objMethod = classTarget.getMethod(methodName, par);
        //5. 获取该方法上的事务注解
        MyTransactional annotation = objMethod.getDeclaredAnnotation(MyTransactional.class);
        return annotation;
    }

    /**
     * 异常通知进行 回滚事务
     */
    @AfterThrowing("execution(* com.gary.demo.service.*.*(..))")
    public void afterThrowing() {
        // 获取当前事务 直接回滚
        System.out.println("[异常通知进行 回滚事务]===========>");
        transactionUtil.rollback(transactionStatus);
    }
}

第一个条件 AOP 实现

下面实现 编程式事务逻辑

package com.gary.demo.support;

import com.gary.demo.transaction.MyTransactionStatus;
import org.springframework.stereotype.Component;

import java.sql.Connection;
import java.sql.SQLException;

@Component
public class MyAbstractPlatformTransactionManager {
    MyTransactionStatus transactionStatus = new MyTransactionStatus();

    public MyTransactionStatus getTransaction() throws SQLException {
        Connection con = null;
        try {
            con = transactionStatus.getConnection();
        } catch (Exception throwables) {
            throwables.printStackTrace();
        } finally {
            if (con != null) {
                con.close();
            }
        }
        return transactionStatus;
    }

    public void commit(MyTransactionStatus transaction) throws SQLException {
        transactionStatus.getConnection().commit();
    }

    public void rollback(MyTransactionStatus transaction) throws SQLException {
        Connection connection = transaction.getConnection();
        connection.rollback();
    }

}
package com.gary.demo.transaction;

import com.gary.demo.support.MyAbstractPlatformTransactionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.sql.SQLException;

/**
 * 手写编程式事务
 */
@Component
public class TransactionUtil {

    // 全局接受事务状态
    private MyTransactionStatus transactionStatus;

    // 获取事务源
    @Autowired
    private MyAbstractPlatformTransactionManager dataSourceTransactionManager;

    // 开启事务
    public MyTransactionStatus begin() {
        System.out.println("开启事务");
        try {
            transactionStatus = dataSourceTransactionManager.getTransaction(new MyTransactionDefinition());
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return transactionStatus;
    }

    // 提交事务
    public void commit(MyTransactionStatus transaction) {
        System.out.println("提交事务");
        if (dataSourceTransactionManager != null) {
            try {
                dataSourceTransactionManager.commit(transaction);
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }

    // 回滚事务
    public void rollback(MyTransactionStatus transaction) {
        System.out.println("回滚事务...");
        if (dataSourceTransactionManager != null) {
            try {
                dataSourceTransactionManager.rollback(transaction);
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }


//    ThreadLocal<Connection> threadLocal = new ThreadLocal<>();
//
//    public ThreadLocal<Connection> getThreadLocal() {
//        return threadLocal;
//    }
//
//    public void setThreadLocal(ThreadLocal<Connection> threadLocal) {
//        this.threadLocal = threadLocal;
//    }
}
package com.gary.demo.transaction;

import java.sql.Connection;
import java.sql.DriverManager;

public class MyTransactionStatus {
    Connection connection;

    public MyTransactionStatus() {
    }

    static final String JDBC_DRIVER = "com.mysql.cj.jdbc.Driver";
    static final String DB_URL = "jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai";
    static final String USER = "root";
    static final String PASS = "123456";


    public Connection getConnection() {
        // 注册 JDBC 驱动
        try {
            Class.forName(JDBC_DRIVER);
            // 打开链接
            System.out.println("连接数据库...");
            connection = DriverManager.getConnection(DB_URL, USER, PASS);
            connection.setAutoCommit(false);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return connection;
    }

}
业务处理类
public interface UserService {
    void addUser();
    void deleteUser();
}

import com.gary.demo.annotation.MyTransactional;
import com.gary.demo.service.UserService;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {

    @MyTransactional
    @Override
    public void addUser() {
        System.out.println("[执行方法] addUser() =======================>");
    }

    @MyTransactional
    @Override
    public void deleteUser() {
        System.out.println("[执行方法] deleteUser() =======================>");
        throw new RuntimeException("deleteUser() 执行异常");
    }
}

 测试演示

  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Coder_Boy_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值