@RestController
public class TestController {
@Autowired
UserNewService userNewService;
@RequestMapping("/save/user")//--->①
public String save() {
UserNew userNew = new UserNew();
userNew.setAge(12);
userNew.setName("java");
userNewService.saveUser(userNew);//--->②
return "ok";
}
}
@Service
public class UserNewServiceImpl implements UserNewService {
@Autowired
private UserNewRepository userNewRepository;
// tx 抛异常 保存情况
// save REQUIRED no no
// save2 REQUIRES_NEW yes no
// save REQUIRED yes no
// save2 REQUIRES_NEW no no
@Transactional(
value = "mysqlTransactionManager",
rollbackFor = {Exception.class, RuntimeException.class},
propagation = Propagation.REQUIRED,
isolation = Isolation.DEFAULT
)
@Override
public void saveUser(UserNew userNew) {
//org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor.CrudMethodMetadataPopulatingMethodInterceptor.invoke()
//ReflectiveMethodInvocation.proceed()
//TransactionInterceptor.invoke()
//org.springframework.transaction.interceptor.TransactionAspectSupport
userNewRepository.save(userNew);//--->③
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
//UserNew user = new UserNew();
//user.setName("22222");
//user.setAge(222);
//saveUser2(user);
throw new RuntimeException("异常发生了");//--->④
}
@Transactional(
value = "mysqlTransactionManager",
rollbackFor = {Exception.class, RuntimeException.class},
propagation = Propagation.REQUIRES_NEW,
isolation = Isolation.DEFAULT
)
@Override
public void saveUser2(UserNew user) {
userNewRepository.save(user);
}
}
逻辑分析:
1: RequestMappingHandlerAdapter来处理requestmapping对应的请求
RequestMappingHandlerAdapter.invokeHandlerMethod()
-->ServletInvocableHandlerMethod.invokeAndHandle()
-->InvocationHandlerMethod.invokeForRequest()
-->InvocableHandlerMethod.doInvoke()
执行TestController save 方法的业务代码 , 当执行到Userservice.save方法的时候
CglibAopProxy.intercept()
class ReflectiveMethodInvocation{
@Override
@Nullable
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();
}
}
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
//强转为interceptorOrInterceptionAdvice 调用invoke-->交个事物的拦截器处理
//就是交给了TransactionInterceptor, 该类在事物处理中扮演重要角色
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
}
class TransactionInterceptor{
public Object invoke(final MethodInvocation invocation) throws Throwable {
// Work out the target class: may be {@code null}.
// The TransactionAttributeSource should be passed the target class
// as well as the method, which may be from an interface.
Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
// Adapt to TransactionAspectSupport's invokeWithinTransaction...
return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
}
}
//TransactionAspectSupport是事物处理核心功能
class TransactionAspectSupport{
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
final InvocationCallback invocation) throws Throwable {
// If the transaction attribute is null, the method is non-transactional.
TransactionAttributeSource tas = getTransactionAttributeSource();
//获取事物的注解属性包括quolifier, rollbackon
final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
//根据quolifiter来判断使用哪个事物管理器
final PlatformTransactionManager tm = determineTransactionManager(txAttr);
//join point 连接点
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
// Standard transaction demarcation with getTransaction and commit/rollback calls.
//创建TransactionInfo对象,将事物和当前的线程进行绑定
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
Object retVal = null;
try {
// This is an around advice: Invoke the next interceptor in the chain.
// This will normally result in a target object being invoked.
//调用ReflectiveMethodInvocation的proceedWithInvocation方法
retVal = invocation.proceedWithInvocation();
}
catch (Throwable ex) {
// target invocation exception
//如果有抛异常,进行rollback
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
cleanupTransactionInfo(txInfo);
}
//提交事物
commitTransactionAfterReturning(txInfo);
return retVal;
}
else {
...
}
}
}
在ReflectiveMethodInvocation 里面, 在执行代码的业务代码的时候可能有很多的xxintercepter, ReflectiveMethodInvocation根据类型
来判断使用哪个拦截器 , 那么TransactionInterceptor 是用来拦截事物业务代码的处理的拦截器
那么TransactionInterceptor是怎么定义的呢?
可以理解为ProxyTransactionManagementConfiguration定义了一个aop的切面
个人的见解
springboot 启动的时候通过自动配置类ProxyTransactionManagementConfiguration
创建了事物的拦截器来扫描系统项目里面的@Transactinal所有的注解的方法 作为事物的切入点
最终返回一个BeanFactoryTransactionAttributeSourceAdvisor 就是advisor 通知
执行业务代码的时候通过拦截器TransactionInterceptor 来处理事物的编制业务
这不就是AOP吗~~~
从TransactionAspectSupport的业务代码就可清楚的看到 当业务代码抛出异常的时候,然后进行回滚,如果没有异常,提交事物;
spring boot jap 的事物的实现就是一个基于注解的aop是实现的;