Spring源码分析:事务是如何进行拦截的

示例代码

Service

public class BlogServiceImpl {
	@Transactional(readOnly = true)
	public List<Blog> findAllBlog(Blog blog) {
		return blogMapper.findAllBlog(blog);
	}
}

Mapper

public interface BlogMapper {
	public List<Blog> findAllBlog(Blog blog);
}

TransactionInterceptor事务拦截器

Spring容器启动的时候会生成代理对象,生成代理对象的同时会去装配每个代理对象的拦截器、切面。

CglibAopProxy.getProxy

因为我的Service类是没有继承接口的,所以用的是Cglib代理。CglibAopProxy.getProxy方法会创建一个Enhancer对象,装配父类、接口、命名规则和回调拦截器等。getCallbacks方法创建代理对象的回调拦截器。
在这里插入图片描述

代理回调过滤器

ProxyCallbackFilter.accept

调用AdvisedSupport.getInterceptorsAndDynamicInterceptionAdvice从方法拦截器缓存中获取指定方法的拦截器对象,如果为空,就调用DefaultAdvisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice获取方法拦截器。

获取到事务拦截器TransactionInterception
在这里插入图片描述
在这里插入图片描述

DynamicAdvisedInterceptor

创建CglibMethodInvocation对象,然后调用该对象的proceed方法,实际上调用的是父类ReflectiveMethodInvocation的proceed方法(如果是使用的Jdk代理,就是创建ReflectiveMethodInvocation对象)。然后调用TransactionInterceptor的invoke方法。
在这里插入图片描述
调用TransactionAspectSupport的invokeWithinTransaction方法,获取事务属性(隔离级别,传播机制、是否只读);获取事务管理器DataSourceTrasactionManager,通过事务管理器开启数据库连接,开启事务;调用AbstractPlatformTransactionManager的getTransaction获取事务;入参是一个TransactionDefinition,TransactionAttribute继承了TransactionDefinition。
在这里插入图片描述
如果是查询语句,设置事务为只读操作。
在这里插入图片描述
在这里插入图片描述

事务回滚

只有抛出的异常是RuntimeException或是Error,事务才会进行回滚;遇到检查异常(checkedException)不回滚。

DefaultTransactionAttribute.rollbackOn方法

public boolean rollbackOn(Throwable ex) {
	return (ex instanceof RuntimeException || ex instanceof Error);
}

猜你喜欢

转载自blog.csdn.net/u012734723/article/details/107746535
今日推荐