详解Spring的声明式事务

事务(Transactional):

在软件开发领域,全有或全无的操作被称作事务,事务具有四个特性:ACID。

A:Atomic 原子性    确保事务中的所有操作全部发生或全部不发生
C:Consistent 一致性    事务的执行结果是确定
I:Isolated 隔离性     事务是彼此隔离的,避免同步读写相同数据
D:Durable 持久性     事务的结果是持久化的

Spring提供的事务管理器:
DataSourceTransactionManager  用于对jdbc和ibatis进行持久化的场景,实现了PlatformTransactionManager接口


利用IOC实例化配置如下:

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	<property name="dataSource" ref="dataSource" />
</bean>

事务属性:

1、传播行为:定义了何时要创建一个事务或何时使用已有的事务;
2、隔离级别:定义了一个事务可能受其他并发事务影响的程度;
3、回滚规则:定义什么异常下回滚
4、事务超时:自动回滚时间
5、是否只读:对读数据库操作加声明,系统就会对该操作优化

Spring中声明事务的注解如下:

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
	// 事务名
	String value() default "";
	// 事务传播行为
	Propagation propagation() default Propagation.REQUIRED;
	// 隔离级别
	Isolation isolation() default Isolation.DEFAULT;
	// 事务超时
	int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;
	// 是否只读
	boolean readOnly() default false;
	// 回滚规则

	// 需要回滚的异常
	Class<? extends Throwable>[] rollbackFor() default {};
	//
	String[] rollbackForClassName() default {};
	// 不需要回滚的异常
	Class<? extends Throwable>[] noRollbackFor() default {};
	//
	String[] noRollbackForClassName() default {};

}

<tx:annotation-driven transaction-manager="transactionManager"/>
上面的配置告诉Spring检查上下文中所有的Bean并查找使用@Transactional注解的Bean,不论注解级别是用在类级别上还是方法级别上,
找到Bean后会自动为它添加事务通知。

事务拦截器(AOP)

TransactionInterceptor调用invoke(final MethodInvocation invocation)进行事务处理

public Object invoke(final MethodInvocation invocation) throws Throwable {
	// Work out the target class: may be <code>null</code>.
	// 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);

	// If the transaction attribute is null, the method is non-transactional.
	final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(invocation.getMethod(), targetClass);
	final PlatformTransactionManager tm = determineTransactionManager(txAttr);
	final String joinpointIdentification = methodIdentification(invocation.getMethod(), 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.proceed();
		}
		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>() {
						public Object doInTransaction(TransactionStatus status) {
							TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
							try {
								return invocation.proceed();
							}
							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 {
								// Reset the TransactionInfo ThreadLocal.
								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();
		}
	}
}

AnnotationTransactionAttributeSource调用findTransactionAttribute(Method method)和findTransactionAttribute(Class<?> clazz)方法
获取TransactionAttribute(@Transactional注解中设置的五个事务属性参数)

类SpringTransactionAnnotationParser调用parseTransactionAnnotation方法生成TransactionAttribute(存储事务属性)

如果事务属性为空,则认为为非事务方法,直接调用原方法

CallbackPreferringPlatformTransactionManager调用execute(TransactionDefinition definition, TransactionCallback<T> callback)

TransactionCallback是处理事务的回调模板类(接口)

CallbackPreferringPlatformTransactionManager 继承自 PlatformTransactionManager

DataSourceTransactionManager实现的事务提交与回滚方法:


@Override
protected void doCommit(DefaultTransactionStatus status) {
	DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
	Connection con = txObject.getConnectionHolder().getConnection();
	if (status.isDebug()) {
		logger.debug("Committing JDBC transaction on Connection [" + con + "]");
	}
	try {
		con.commit();
	}
	catch (SQLException ex) {
		throw new TransactionSystemException("Could not commit JDBC transaction", ex);
	}
}

@Override
protected void doRollback(DefaultTransactionStatus status) {
	DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
	Connection con = txObject.getConnectionHolder().getConnection();
	if (status.isDebug()) {
		logger.debug("Rolling back JDBC transaction on Connection [" + con + "]");
	}
	try {
		con.rollback();
	}
	catch (SQLException ex) {
		throw new TransactionSystemException("Could not roll back JDBC transaction", ex);
	}
}
依懒接口:java.sql.Connection

Connection最终实现的类:com.mysql.jdbc.ConnectionImpl.class

利用visualvm查看JVM中的实例结果如下:

可以看出AOP代理和回调


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值