spring声明式事务源码剖析(中)
来源:互联网 发布:ssh建立连接的端口号 编辑:程序博客网 时间:2024/06/06 01:01
TransactionInterceptor这个类我们在上一篇中已经认识了,这一篇我们来看一下,它是如何完成事务的拦截。spring代码版本v.4.2.4.RELEASE.
TransactionInterceptor.invoke
@Overridepublic Object invoke(final MethodInvocation invocation) throws Throwable { // Work out the target class: may be {@code null}. // 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); // Adapt to TransactionAspectSupport's invokeWithinTransaction... return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() { @Override public Object proceedWithInvocation() throws Throwable { return invocation.proceed(); } });}
TransactionAspectSupport.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(); } } }
这个方法开启事务,执行业务方法,关闭事务,返回业务执行结果;
TransactionAspectSupport.createTransactionIfNecessary
这个方法开启事务,事务的开启最终转嫁给 PlatformTransactionManager。对于一般的开发我们都应用单个关系型数据库,所以对应的PlatformTransactionManger为 DataSourceTransactionManager
DataSourceTransactionManager.getTransaction
该方法其父类中实现
AbstractPlatformTransactionManager.getTransaction
/** * This implementation handles propagation behavior. Delegates to * {@code doGetTransaction}, {@code isExistingTransaction} * and {@code doBegin}. * @see #doGetTransaction * @see #isExistingTransaction * @see #doBegin */@Overridepublic final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException { Object transaction = doGetTransaction();// Cache debug flag to avoid repeated checks.boolean debugEnabled = logger.isDebugEnabled();if (definition == null) { // Use defaults if no transaction definition given. definition = new DefaultTransactionDefinition(); //事务不存在时}if (isExistingTransaction(transaction)) { //事务已存在 // Existing transaction found -> check propagation behavior to find out how to behave. return handleExistingTransaction(definition, transaction, debugEnabled);}// Check definition settings for new transaction.if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) { throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout());}// No existing transaction found -> check propagation behavior to find out how to proceed.//事务传播判断if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) { throw new IllegalTransactionStateException( "No existing transaction found for transaction marked with propagation 'mandatory'");}else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED || definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW || definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) { SuspendedResourcesHolder suspendedResources = suspend(null); if (debugEnabled) { logger.debug("Creating new transaction with name [" + definition.getName() + "]: " + definition); } try { boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER); DefaultTransactionStatus status = newTransactionStatus( definition, transaction, true, newSynchronization, debugEnabled, suspendedResources); doBegin(transaction, definition); //开启事务 prepareSynchronization(status, definition);//同步事务 return status; } catch (RuntimeException ex) { resume(null, suspendedResources); throw ex; } catch (Error err) { resume(null, suspendedResources); throw err; }}else { // Create "empty" transaction: no actual transaction, but potentially synchronization. if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) { logger.warn("Custom isolation level specified but no actual transaction initiated; " + "isolation level will effectively be ignored: " + definition); } boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS); return prepareTransactionStatus(definition, null, true, newSynchronization, debugEnabled, null);}
}
方法定义如上.在学习spring事务时,需要注意如下几个类或接口
TransactionDefinition:事务接口TransactionAttribute 事务接口扩展TransactionStatus 事务状态PlatformTransactionManager 统一事务管理平台
对于如上的spring事务传播机制进行总结如下(我相信很多人都看过这个表格)
AbstractPlatformTransactionManager.doBegin(Object transaction, TransactionDefinition definition)
它的实现在子类DataSourceTransactionManager
DataSourceTransactionManager.doBegin
这个方法获取Connection 并打开事务,它依赖于关系数据库的事务支持程度,所以说spring不重新发明轮子。
关于应用xml配置的声明式事务,已经至此完毕,对于应用注解式的事务管理,我们下篇再剖析。
- spring声明式事务源码剖析(中)
- spring声明式事务源码剖析(上)
- spring声明式事务源码剖析(下)
- spring声明式事务源码解析
- Spring编程式事务与声明式事务源码分析
- spring中jdbc声明式事务和spring基于xmlschema、annotation的声明式事务(事务3)
- 在Spring中实现声明式事务
- spring声明式事务
- Spring---声明式事务
- Spring声明式事务
- Spring声明式事务
- spring 声明式事务
- 声明式事务 spring
- Spring声明式事务
- Spring声明式事务
- spring 声明式事务
- Spring声明式事务
- Spring 声明式事务
- 区块链2.0(六):以太坊—开放的智能合约完整解决方案
- ilnkBell隐私政策
- Android
- linux学习笔记(10)
- html表单基础
- spring声明式事务源码剖析(中)
- 解决IE浏览器下document click事件失效问题
- Java NIO系列教程(6):Selector
- 剑指offer(23)—二叉搜索树的后序遍历序列
- 【学习笔记】jQuery的实现原理
- Unity 使用 Runtime NavMesh(运行时导航),实现AI在场景变化时,重新计算路线
- POJ1273-Drainage Ditches
- 一个想法照进现实-《IT连》创业项目:聊聊最近两三事
- 对于ORACLE RAC集群修改MAX_STRING_SIZE的方法(varchar2字段扩展到32K)