Spring事务源码详解

一、什么是事务

事务:多个操作,要么都做,要么都不做。

数据库的事务管理流程

  1. 开启事务
  2. 执行多个操作
  3. 提交或回滚

二、Spring事务

Spring的事务管理跟数据库的事务管理也是一样的。 

  • 支持多种不同的事务管理实现

贴一下spring实现事务管理的xml配置:

三、Spring事务源码

目前我研究的是:

一个接口,一个抽象类,两个实现类

  • 接口是:PlatformTransactionManager.class
  • 抽象类:AbstractPlatformTransactionManager.class
  • 两个实现类:DataSourceTransactionManager.class(可实现多个方法在一个事务中)
    JtaTransactionManager.class(分布式事务管理器,springboot只提供了规范,需要开发者自己去实现)

3.1 PlatformTransactionManager(平台事务管理器)

3.1.1 方法图

 可以看到他的方法无非就是开启事务、提交、回滚。

3.1.1.1 TransactionDefinition

TransactionDefinition——是getTransaction()方法中入参,我们看看它的组成:

看到了吗,它就是事务定义类——就是我们@Transaction注解里的各种参数。

由上图延伸出问题:

  • spring有几种事务隔离级别,几种传播行为?

 TransactionDefinition的实现类与继承关系:

3.1.2 所有实现与继承

DataSourceTransactionManager类继承图:DataSourceTransactionManager后面会详细讲解。

3.1.3 @Transactional注解

3.2 切面代码——TransactionInterceptor

在应用系统调用声明@Transactional 的目标方法时,Spring Framework 默认使用 AOP 代理,在代码运行时生成一个代理对象,根据@Transactional 的属性配置信息,这个代理对象决定该声明@Transactional 的目标方法是否由拦截器 TransactionInterceptor 来使用拦截,在 TransactionInterceptor 拦截时,会在在目标方法开始执行之前创建并加入事务,并执行目标方法的逻辑, 最后根据执行情况是否出现异常,利用抽象事务管理器(图 2 有相关介绍)AbstractPlatformTransactionManager 操作数据源 DataSource 提交或回滚事务。

3.2.1 

TransactionInterceptor.invoke——>invokeWithinTransaction 就是执行@Transactional注解标注的代码逻辑。

 

开启事务:

 

异常是否回滚:

 3.2.2 invokeWithinTransaction代码

protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation)
			throws Throwable {

		// If the transaction attribute is null, the method is non-transactional.
		final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
		final PlatformTransactionManager tm = determineTransactionManager(txAttr);
		final String joinpointIdentification = methodIdentification(method, targetClass);

		if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
			// Standard transaction demarcation with getTransaction and commit/rollback calls.
			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.
				retVal = invocation.proceedWithInvocation();
			}
			catch (Throwable ex) {
				// target invocation exception
				completeTransactionAfterThrowing(txInfo, ex);
				throw ex;
			}
			finally {
				cleanupTransactionInfo(txInfo);
			}
			commitTransactionAfterReturning(txInfo);
			return retVal;
		}

		else {
			// It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
			try {
				Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr,
						new TransactionCallback<Object>() {
							@Override
							public Object doInTransaction(TransactionStatus status) {
								TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
								try {
									return invocation.proceedWithInvocation();
								}
								catch (Throwable ex) {
									if (txAttr.rollbackOn(ex)) {
										// A RuntimeException: will lead to a rollback.
										if (ex instanceof RuntimeException) {
											throw (RuntimeException) ex;
										}
										else {
											throw new ThrowableHolderException(ex);
										}
									}
									else {
										// A normal return value: will lead to a commit.
										return new ThrowableHolder(ex);
									}
								}
								finally {
									cleanupTransactionInfo(txInfo);
								}
							}
						});

				// Check result: It might indicate a Throwable to rethrow.
				if (result instanceof ThrowableHolder) {
					throw ((ThrowableHolder) result).getThrowable();
				}
				else {
					return result;
				}
			}
			catch (ThrowableHolderException ex) {
				throw ex.getCause();
			}
		}
	}

方法基本逻辑分析:

  1. 获取事务属性,根据事务属性获取事务管理器。
  2. 判断属性是否为空,或者事务管理是否是CallbackPreferringPlatformTransactionManager类型,如果是该类型,则会执行事务管理器的execute方法。
  3. 生成一个封装事务管理器、事务属性、方法签名字符串、事务状态对象的TransactionInfo事务信息对象,改对象会在事务回滚或者失败时起作用。
  4. 调用目标对象方法或者下一个过滤器的方法
  5. 如果方法由异常则执行 completeTransactionAfterThrowing 方法,调用事务管理器的回滚方法。如果没有异常,调用 commitTransactionAfterReturning 提交方法。最后返回返回值

 四、DataSourceTransactionManager

多个方法要操作一个db,想要设置成一个事务,spring如何实现?
——怎么让多个方法拿到同一个连接。
——DataSourceTransactionManager

4.1 事务管理器中的抽象类(模板方法),代码解读

AbstractPlatformTransationManager.java是一个抽象类

doGetTransation()是一个抽象方法。不同的子类可以实现自己的doGetTransaction()方法。
——这就什么设计模式?模板方法设计模式

AbstractPlatformTransationManager标准的commit方法:

commit调用过程:
commit——>processCommit(defStatus)——>doCommit(status);
同样的,其中doCommit()是抽象方法,doRollback()也是抽象方法。

为什么在抽象层实现,因为流程是一样的,只是个别方法有些许差异。

 4.2 数据源的事务管理器代码解读

TreadLocal是一个线程一份,那为什么所有线程共用了ThreadLocal?
——TreadLocal是随着线程消失而消失的,新的线程与老线程无关。

4.2.1 连接的逻辑

开启事务:

 

 

doBegin又是抽象方法:为什么用protected修饰,因为要让子类调用

查看它在DataSourceTransactionManager中的实现:

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值