spring事务@Transactional实现原理

spring是如何实现事务的 AOP + 动态代理
使用AOP拦截到我们加了@myAnnoTrancation的方法 然后开启事务 使用动态代理调用当前方法 提交事务 同时使用AOP异常通知 做回滚的监听


// 自定义注解

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

}

// 事务管理

@Component
public class MyTransactionManager {

private TransactionStatus transactionStatus;

@Autowired
private DataSourceTransactionManager dataSourceTransactionManager;

/**
* 开启事务
*/
public TransactionStatus begin() {
TransactionStatus status = dataSourceTransactionManager.getTransaction(new DefaultTransactionAttribute());
return status;
}

/**
* 事务回滚
**/

public void rollBack() {
System.out.println("事务回滚");
dataSourceTransactionManager.rollback(transactionStatus);
}

/**
* 事务提交
* **/
public void commit(TransactionStatus transactionStatus) {
dataSourceTransactionManager.commit(transactionStatus);
}

}

//针对事务的拦截处理

@Aspect
@Component
@Transactional
public class MyAopTransaction {


@Autowired
private MyTransactionManager myTransactionManager;


TransactionStatus transactionStatus = null;

 

// ProceedingJoinPoint AOP获取连接到对象
@Around("execution(* com.sunny.service.StudentService*.*(..))")
public Object around(ProceedingJoinPoint point) throws Throwable {
System.out.println("拦截起作用");
// 先获取拦截的方法 判断方法上有没有@Transaction注解
MyAnnoTrancation myAnnoTrancation = geMyAnnoTrancation(point);

// 开启事务
if (myAnnoTrancation != null) {
transactionStatus = myTransactionManager.begin();
}
// 调用拦截方法
Object proceed = point.proceed();

if (myAnnoTrancation != null) {
myTransactionManager.commit(transactionStatus);
}

point.getClass().getAnnotations();
return proceed;
}

 

/**
* 异常通知进行 回滚事务
*/
@AfterThrowing(throwing = "ex", pointcut = "execution(* com.sunny.service.StudentService*.*(..))")
public void afterThrowing(JoinPoint point, Throwable ex) {
System.out.println("异常捕获" + ex.getMessage());
// 获取当前事务 直接回滚
if (transactionStatus != null) {
myTransactionManager.rollBack();
}
}

 

// 获取拦截对象释放被打上 自定义注解

public MyAnnoTrancation geMyAnnoTrancation(ProceedingJoinPoint point) {
String methodName = point.getSignature().getName();
Class<? extends Object> classTarget = point.getTarget().getClass();
try {
Method method = classTarget.getMethod(methodName, classTarget.getClasses());
MyAnnoTrancation myannotation = method.getAnnotation(MyAnnoTrancation.class);
if (myannotation != null) {
return myannotation;
}
return null;
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
return null;

}

posted @ 2020-08-23 18:13  爵士灬  阅读(1163)  评论(0编辑  收藏  举报