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);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值