Spring 事务模板方法设计模式
Posted linlf03
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring 事务模板方法设计模式相关的知识,希望对你有一定的参考价值。
接上一篇文章
上一篇讲到了doGetTransaction方法
一、模板方法设计模式
这里涉及到了一个经典的设计模式:模板方法
如下图:
AbstractPlatformTransactionManager实现了PlatformTranscationManager接口
DatasourceTransactionManager,HibernateTransactionManager等继承了AbstractPlatformTransactionManager类
AbstractPlatformTransactionManager类中定义了事务处理的若干方法。 其中获得事务,提交事务,回滚事务由具体的子类实现。
二、进入doGetTransaction的其中一个实现类Hibernate3中的HibernateTransactionManager 类
进入doGetTransaction方法
@Override protected Object doGetTransaction() HibernateTransactionObject txObject = new HibernateTransactionObject(); txObject.setSavepointAllowed(isNestedTransactionAllowed()); SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(getSessionFactory()); if (sessionHolder != null) if (logger.isDebugEnabled()) logger.debug("Found thread-bound Session [" + SessionFactoryUtils.toString(sessionHolder.getSession()) + "] for Hibernate transaction"); txObject.setSessionHolder(sessionHolder); else if (this.hibernateManagedSession) try Session session = getSessionFactory().getCurrentSession(); if (logger.isDebugEnabled()) logger.debug("Found Hibernate-managed Session [" + SessionFactoryUtils.toString(session) + "] for Spring-managed transaction"); txObject.setExistingSession(session); catch (HibernateException ex) throw new DataAccessResourceFailureException( "Could not obtain Hibernate-managed Session for Spring-managed transaction", ex); if (getDataSource() != null) ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(getDataSource()); txObject.setConnectionHolder(conHolder); return txObject;
1、创建HibernateTransactionObject对象
HibernateTransactionObject txObject = new HibernateTransactionObject();
HibernateTransactionObject 是一个Hibernate事务对象,代表一个SessionHolder。被HibernateTransactionManger用作事务对象。
2、进入SessionHolder
SessionHolder: session持有者,包装了一个Hibernate Session和一个Hibernate事务
三 、进入doGetTransaction的其中一个实现类JDBC中的DataSourceTransactionManager 类
进入doGetTransaction方法
@Override protected Object doGetTransaction() DataSourceTransactionObject txObject = new DataSourceTransactionObject(); txObject.setSavepointAllowed(isNestedTransactionAllowed()); ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource); txObject.setConnectionHolder(conHolder, false); return txObject;
1、创建DataSourceTransactionObject实例
DataSourceTransactionObject txObject = new DataSourceTransactionObject();
进入DataSourceTransactionObject
DataSourceTransactionObject也是继承自JdbcTransactionObjectSupport
三、回到AbstractPlatformTransactionManager类的getTransaction方法
进入如下代码
如果已经存在事务,则检查事务的传播行为
2、进入handleExistingTransaction方法
/** * Create a TransactionStatus for an existing transaction. */ private TransactionStatus handleExistingTransaction( TransactionDefinition definition, Object transaction, boolean debugEnabled) throws TransactionException if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) throw new IllegalTransactionStateException( "Existing transaction found for transaction marked with propagation ‘never‘"); if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) if (debugEnabled) logger.debug("Suspending current transaction"); Object suspendedResources = suspend(transaction); boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS); return prepareTransactionStatus( definition, null, false, newSynchronization, debugEnabled, suspendedResources); if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) if (debugEnabled) logger.debug("Suspending current transaction, creating new transaction with name [" + definition.getName() + "]"); SuspendedResourcesHolder suspendedResources = suspend(transaction); 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 beginEx) resumeAfterBeginException(transaction, suspendedResources, beginEx); throw beginEx; catch (Error beginErr) resumeAfterBeginException(transaction, suspendedResources, beginErr); throw beginErr; if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) if (!isNestedTransactionAllowed()) throw new NestedTransactionNotSupportedException( "Transaction manager does not allow nested transactions by default - " + "specify ‘nestedTransactionAllowed‘ property with value ‘true‘"); if (debugEnabled) logger.debug("Creating nested transaction with name [" + definition.getName() + "]"); if (useSavepointForNestedTransaction()) // Create savepoint within existing Spring-managed transaction, // through the SavepointManager API implemented by TransactionStatus. // Usually uses JDBC 3.0 savepoints. Never activates Spring synchronization. DefaultTransactionStatus status = prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null); status.createAndHoldSavepoint(); return status; else // Nested transaction through nested begin and commit/rollback calls. // Usually only for JTA: Spring synchronization might get activated here // in case of a pre-existing JTA transaction. boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER); DefaultTransactionStatus status = newTransactionStatus( definition, transaction, true, newSynchronization, debugEnabled, null); doBegin(transaction, definition); prepareSynchronization(status, definition); return status; // Assumably PROPAGATION_SUPPORTS or PROPAGATION_REQUIRED. if (debugEnabled) logger.debug("Participating in existing transaction"); if (isValidateExistingTransaction()) if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) Integer currentIsolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel(); if (currentIsolationLevel == null || currentIsolationLevel != definition.getIsolationLevel()) Constants isoConstants = DefaultTransactionDefinition.constants; throw new IllegalTransactionStateException("Participating transaction with definition [" + definition + "] specifies isolation level which is incompatible with existing transaction: " + (currentIsolationLevel != null ? isoConstants.toCode(currentIsolationLevel, DefaultTransactionDefinition.PREFIX_ISOLATION) : "(unknown)")); if (!definition.isReadOnly()) if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) throw new IllegalTransactionStateException("Participating transaction with definition [" + definition + "] is not marked as read-only but existing transaction is"); boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER); return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null);
以上是关于Spring 事务模板方法设计模式的主要内容,如果未能解决你的问题,请参考以下文章