事务(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


springamqp声明式配置不自动创建队列_回滚

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

springamqp声明式配置不自动创建队列_Spring_02

可以看出AOP代理和回调

springamqp声明式配置不自动创建队列_java_03