@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() 执行异常");
}
}
测试演示