`
dylan0514sina.cn
  • 浏览: 94961 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

AbstractPlatformTransactionManager

 
阅读更多
AbstractPlatformTransactionManager是Spring提供事务支持的核心处理类,它的功能可大致划分
  处理传播行为
  处理挂起与恢复
  检查只读标志,处理回滚
  处理回调

  了解事务传播行为
  PROPAGATION_REQUIRED 支持已存在的事务或开启新事务
  PROPAGATION_SUPPORTS 支持已存在的事务或挂起当前事务,非事务的运行
  PROPAGATION_MANDATORY 必须由已存在的事务支持,否则抛出异常
  PROPAGATION_REQUIRES_NEW 总是开启新事务,如果已存在事务,则挂起
  PROPAGATION_NOT_SUPPORTED 总是非事务运行,如果已存在事务,则挂起
  PROPAGATION_NEVER  如果已存在事务,则抛出异常
  PROPAGATION_NESTED 总会创建内部事务,对JDBC3.0以上来说,使用保存点技术支持;对JTA来说,事务管理器必须支持嵌套事务
  这前面6中与EJB中事务传播行为一致,最后一种是Spring特有。
  
  嵌套事务
  内部事务提交或回滚不影响外部事务。必须处理完内部事务才能返回外部事务的处理,处理结果不能影响已处理完的内部事务。Spring实现中由JDBC保存点技术或JTA事务管理器支持
当不使用JDBC保存点技术时,嵌套事务的doBegin方法将开始,同时如果外部事务使用Spring同步机制,则嵌套事务并不能激活Spring同步:同一时刻,单个线程只能激活一次Spring同步。
  JDBC保存点技术是Spring支持嵌套事务的首选,原理是:先设置保存点:在提交时释放;回滚时回滚到创建保存点的地方从而避免了不必要的整个事务回滚。支持Spring提供的任意AbstractDataSourceTransactionManager实现,比如DataSourceTransactionManager.
  否则,使用非JTATransactionManager的其他Spring事务管理器实现,比如(DataSourceTransactionManager和HibernateTransactionManager)在doBegin方法中,可以清晰知道当前Holder已经被新Holder覆盖掉,也就说明之前的外面的连接在内部事务完成之后不可获取了;DataSourceTransactionManager片段
  
/**
	 * This implementation sets the isolation level but ignores the timeout.
	 */
	@Override
	protected void doBegin(Object transaction, TransactionDefinition definition) {
		DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
		Connection con = null;

		try {
			if (txObject.getConnectionHolder() == null ||
					txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
				Connection newCon = this.dataSource.getConnection();
				if (logger.isDebugEnabled()) {
					logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");
				}
				txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
			}

			txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
			con = txObject.getConnectionHolder().getConnection();

			Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
			txObject.setPreviousIsolationLevel(previousIsolationLevel);

			// Switch to manual commit if necessary. This is very expensive in some JDBC drivers,
			// so we don't want to do it unnecessarily (for example if we've explicitly
			// configured the connection pool to set it already).
			if (con.getAutoCommit()) {
				txObject.setMustRestoreAutoCommit(true);
				if (logger.isDebugEnabled()) {
					logger.debug("Switching JDBC Connection [" + con + "] to manual commit");
				}
				con.setAutoCommit(false);
			}
			txObject.getConnectionHolder().setTransactionActive(true);

			int timeout = determineTimeout(definition);
			if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
				txObject.getConnectionHolder().setTimeoutInSeconds(timeout);
			}

			// Bind the session holder to the thread.
			if (txObject.isNewConnectionHolder()) {
				TransactionSynchronizationManager.bindResource(getDataSource(), txObject.getConnectionHolder());
			}
		}

		catch (Exception ex) {
			DataSourceUtils.releaseConnection(con, this.dataSource);
			throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);
		}
	}

  如果在应用中之前保留连接引用(大多数应用中直接或间接地使用JDBCTEmplate或JDBCDaoSupport或hiberateTemplate或hibernateDaoSupport),在接下来的操作之前必须绑定资源TransactionSynchronizationManager.bindResource(DataSource,new ConnectionHolder(con)),不然很可能下个操作时会另一个新开的连接,而新开的连接上的操作在事务提交时是无效的。
  
  DataSourceUtils.getConnection不支持JTA同步。在JTATransactionManager管理下,如果外部事务Spring同步根本没有激活,那DataSourceUtils.getConnection都会返回新的连接,而且必须手动关闭连接;如果Spring同步激活了,则DataSourceUtils.getConnection每次返回的是同一个连接,而且不必手动关闭连接。

public static Connection doGetConnection(DataSource dataSource) throws SQLException {
		Assert.notNull(dataSource, "No DataSource specified");

		ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
		if (conHolder != null && (conHolder.hasConnection() || conHolder.isSynchronizedWithTransaction())) {
			conHolder.requested();
			if (!conHolder.hasConnection()) {
				logger.debug("Fetching resumed JDBC Connection from DataSource");
				conHolder.setConnection(dataSource.getConnection());
			}
			return conHolder.getConnection();
		}
		// Else we either got no holder or an empty thread-bound holder here.

		logger.debug("Fetching JDBC Connection from DataSource");
		Connection con = dataSource.getConnection();

		if (TransactionSynchronizationManager.isSynchronizationActive()) {
			logger.debug("Registering transaction synchronization for JDBC Connection");
			// Use same Connection for further JDBC actions within the transaction.
			// Thread-bound object will get removed by synchronization at transaction completion.
			ConnectionHolder holderToUse = conHolder;
			if (holderToUse == null) {
				holderToUse = new ConnectionHolder(con);
			}
			else {
				holderToUse.setConnection(con);
			}
			holderToUse.requested();
			TransactionSynchronizationManager.registerSynchronization(
					new ConnectionSynchronization(holderToUse, dataSource));
			holderToUse.setSynchronizedWithTransaction(true);
			if (holderToUse != conHolder) {
				TransactionSynchronizationManager.bindResource(dataSource, holderToUse);
			}
		}

		return con;
	}


  SessionFactoryUtils.getSession()支持Spring同步,也支持JTA同步。在JTATransactionManager管理下,SessionFactoryUtils.getSession()返回的总是同一Session,也不必担心资源的处理。

private static Session doGetSession(
			SessionFactory sessionFactory, Interceptor entityInterceptor,
			SQLExceptionTranslator jdbcExceptionTranslator, boolean allowCreate)
			throws HibernateException, IllegalStateException {

		Assert.notNull(sessionFactory, "No SessionFactory specified");

		Object resource = TransactionSynchronizationManager.getResource(sessionFactory);
		if (resource instanceof Session) {
			return (Session) resource;
		}
		SessionHolder sessionHolder = (SessionHolder) resource;
		if (sessionHolder != null && !sessionHolder.isEmpty()) {
			// pre-bound Hibernate Session
			Session session = null;
			if (TransactionSynchronizationManager.isSynchronizationActive() &&
					sessionHolder.doesNotHoldNonDefaultSession()) {
				// Spring transaction management is active ->
				// register pre-bound Session with it for transactional flushing.
				session = sessionHolder.getValidatedSession();
				if (session != null && !sessionHolder.isSynchronizedWithTransaction()) {
					logger.debug("Registering Spring transaction synchronization for existing Hibernate Session");
					TransactionSynchronizationManager.registerSynchronization(
							new SpringSessionSynchronization(sessionHolder, sessionFactory, jdbcExceptionTranslator, false));
					sessionHolder.setSynchronizedWithTransaction(true);
					// Switch to FlushMode.AUTO, as we have to assume a thread-bound Session
					// with FlushMode.MANUAL, which needs to allow flushing within the transaction.
					FlushMode flushMode = session.getFlushMode();
					if (flushMode.lessThan(FlushMode.COMMIT) &&
							!TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
						session.setFlushMode(FlushMode.AUTO);
						sessionHolder.setPreviousFlushMode(flushMode);
					}
				}
			}
			else {
				// No Spring transaction management active -> try JTA transaction synchronization.
				session = getJtaSynchronizedSession(sessionHolder, sessionFactory, jdbcExceptionTranslator);
			}
			if (session != null) {
				return session;
			}
		}

		logger.debug("Opening Hibernate Session");
		Session session = (entityInterceptor != null ?
				sessionFactory.openSession(entityInterceptor) : sessionFactory.openSession());

		// Use same Session for further Hibernate actions within the transaction.
		// Thread object will get removed by synchronization at transaction completion.
		if (TransactionSynchronizationManager.isSynchronizationActive()) {
			// We're within a Spring-managed transaction, possibly from JtaTransactionManager.
			logger.debug("Registering Spring transaction synchronization for new Hibernate Session");
			SessionHolder holderToUse = sessionHolder;
			if (holderToUse == null) {
				holderToUse = new SessionHolder(session);
			}
			else {
				holderToUse.addSession(session);
			}
			if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
				session.setFlushMode(FlushMode.MANUAL);
			}
			TransactionSynchronizationManager.registerSynchronization(
					new SpringSessionSynchronization(holderToUse, sessionFactory, jdbcExceptionTranslator, true));
			holderToUse.setSynchronizedWithTransaction(true);
			if (holderToUse != sessionHolder) {
				TransactionSynchronizationManager.bindResource(sessionFactory, holderToUse);
			}
		}
		else {
			// No Spring transaction management active -> try JTA transaction synchronization.
			registerJtaSynchronization(session, sessionFactory, jdbcExceptionTranslator, sessionHolder);
		}

		// Check whether we are allowed to return the Session.
		if (!allowCreate && !isSessionTransactional(session, sessionFactory)) {
			closeSession(session);
			throw new IllegalStateException("No Hibernate Session bound to thread, " +
				"and configuration does not allow creation of non-transactional one here");
		}

		return session;
	}


  了解Spring同步时机 
   SYNCHRONIZATION_ALWAYS 总是激活Spring同步,即使非事务情况下
   SYNCHRONIZATION_ON_ACTUAL_TRANSACTION 在事务的情况下激活Spring同步
   SYNCHRONIZATION_NEVER 从不激活Spring同步,即使存在事务

  getTransaction方法处理传播行为
  提供doGetTransaction和isExistingTransaction确认当前是否已存在事务,不同的具体事务管理器有不同的实现,看看DataSourceTransactionManager中这对方法片段。实现细节在之后会讨论。

  @Override
	protected Object doGetTransaction() {
		DataSourceTransactionObject txObject = new DataSourceTransactionObject();
		txObject.setSavepointAllowed(isNestedTransactionAllowed());
		ConnectionHolder conHolder =
		    (ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource);
		txObject.setConnectionHolder(conHolder, false);
		return txObject;
	}

	@Override
	protected boolean isExistingTransaction(Object transaction) {
		DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
		return (txObject.getConnectionHolder() != null && txObject.getConnectionHolder().isTransactionActive());
	}

  如果isExistingTransaction返回false,则
  如果当前definition定义的超时时间无效,则抛出异常
  如果当前definition定义的传播行为是PROPAGATION_MANDATORY ,则抛出异常
  如果当前definition定义的传播行为是PROPAGATION_REQUIRED或PROPAGATION_REQUIRES_NEW或PROPAGATION_NESTED,则调用doBegin开始事务,同时根据transactionSynchronization!=SYNCHRONIZATION_NEVER激活Spring同步并为当前线程设置事务只读,事务有无,隔离级别,事务名称信息;
  如果当前definition定义的传播行为是PROPAGATION_SUPPORTS或PROPAGATION_NOT_SUPPORTED,则根据transactionSynchronization==SYNCHRONIZATION_NEVER激活Spring同步
  
  如果isExistingTransaction返回true,说明当前已存在事务,则
  如果当前definition定义的传播行为是PROPAGATION_NEVER ,则抛出异常
  如果当前definition定义的传播行为是PROPAGATION_NOT_SUPPORTED,则如果Spring激活执行当前所有同步TransactionSynchronization的suspend方法,钝化Spring同步;将存在的事务挂起;挂起当前所有事务只读等信息。根据transactionSynchronization == SYNCHRONIZATION_ALWAYS激活Spring同步并为 当前线程设置新的事务只读,事务有无,隔离级别,事务名称信息;
  如果当前definition定义的传播行为是PROPAGATION_REQUIRES_NEW,则执行同上的挂起操作,同时根据transactionSynchronization != SYNCHRONIZATION_NEVER,执行同上的激活Spring同步
  如果当前definition定义的传播行为是PROPAGATION_NESTED,则
      如果支持保存点技术,则创建保存点,从不激活同步
      否则使用嵌套事务,调用doBegin(如果应用服务器或本地提供的事务管理器不支持嵌套事务则报错)方法同时根据transactionSynchronization != SYNCHRONIZATION_NEVER执行同上的激活Spring同步

   如果当前definition定义的传播行为是PROPAGATION_SUPPORTS或PROPAGATION_REQUIRED,则检查isValidateExistingTransaction设置即是否需要验证当前事务中的只读,隔离级别信息和当前definition中的一致;如果校验没有设置或设置后校验成功之后,根据transactionSynchronization != SYNCHRONIZATION_NEVER激活Spring同步         

   getTransaction会返回TransactionStatus,默认情况下提供DefaultTransactionStatus实例,具体功能
    创建保存点
    设置回滚,事务是否完成
    携带只读,事务对象,是否新事务,是否新同步,已挂起的同步类实例等不可修改信息。我们还必须关注如下方法,它的实现代理到SmartTransactionObject中的回滚标志设置。那这种方式叫全局回滚标志;调用DefaultTransactionStatus设置的回滚叫本地回滚标志。 
/**
	 * Determine the rollback-only flag via checking both the transaction object,
	 * provided that the latter implements the {@link SmartTransactionObject} interface.
	 * <p>Will return "true" if the transaction itself has been marked rollback-only
	 * by the transaction coordinator, for example in case of a timeout.
	 * @see SmartTransactionObject#isRollbackOnly
	 */
	@Override
	public boolean isGlobalRollbackOnly() {
		return ((this.transaction instanceof SmartTransactionObject) &&
				((SmartTransactionObject) this.transaction).isRollbackOnly());
	}

DataSourceTransactionObject代码片段
	public boolean isRollbackOnly() {
			return getConnectionHolder().isRollbackOnly();
		}

JtaTransactionObject代码片段
/**
	 * This implementation checks the UserTransaction's rollback-only flag.
	 */
	public boolean isRollbackOnly() {
		if (this.userTransaction == null) {
			return false;
		}
		try {
			int jtaStatus = this.userTransaction.getStatus();
			return (jtaStatus == Status.STATUS_MARKED_ROLLBACK || jtaStatus == Status.STATUS_ROLLEDBACK);
		}
		catch (SystemException ex) {
			throw new TransactionSystemException("JTA failure on getStatus", ex);
		}
	}
    
   回复
   在getTransaction过程中,发现错误即可回复
   处理事务提交或回滚之后,如果DefaultTransactionStatus.getSuspendedResources不为空可回复

private void cleanupAfterCompletion(DefaultTransactionStatus status) {
		status.setCompleted();
		if (status.isNewSynchronization()) {
			TransactionSynchronizationManager.clear();
		}
		if (status.isNewTransaction()) {
			doCleanupAfterCompletion(status.getTransaction());
		}
		if (status.getSuspendedResources() != null) {
			if (status.isDebug()) {
				logger.debug("Resuming suspended transaction after completion of inner transaction");
			}
			resume(status.getTransaction(), (SuspendedResourcesHolder) status.getSuspendedResources());
		}
	}


     
   JTATransactionManager支持下的,参与性的内部事务有权注册JTA同步
   同步的各个方法调用时机在TransactionSynchronization中介绍过,这里介绍triggerAfterCompletion。该方法代理到同步中的afterCompletion执行,如果当前没有事务或者事务是Spring doBegin方法创建的,则即可执行同步中afterCompletion;否则调用registerAfterCompletionWithExistingTransaction,在JTATransactionManager重写了这个方法:试图查找TransactionSynchronizationRegistry或javax.transaction.TransactionManager注册同步,失败则即可执行同步中afterCompletion。这种做法在之后的事务原则中有介绍
	/**
	 * Trigger <code>afterCompletion</code> callbacks.
	 * @param status object representing the transaction
	 * @param completionStatus completion status according to TransactionSynchronization constants
	 */
	private void triggerAfterCompletion(DefaultTransactionStatus status, int completionStatus) {
		if (status.isNewSynchronization()) {
			List<TransactionSynchronization> synchronizations = TransactionSynchronizationManager.getSynchronizations();
			if (!status.hasTransaction() || status.isNewTransaction()) {
				if (status.isDebug()) {
					logger.trace("Triggering afterCompletion synchronization");
				}
				// No transaction or new transaction for the current scope ->
				// invoke the afterCompletion callbacks immediately
				invokeAfterCompletion(synchronizations, completionStatus);
			}
			else if (!synchronizations.isEmpty()) {
				// Existing transaction that we participate in, controlled outside
				// of the scope of this Spring transaction manager -> try to register
				// an afterCompletion callback with the existing (JTA) transaction.
				registerAfterCompletionWithExistingTransaction(status.getTransaction(), synchronizations);
			}
		}
	}


   事务处理原则: 我发起的事务,只能我能够提交或回滚;参与性的事务没有资格提交,最多只能设置回滚标志(可以注册同步) 。
    Spring中事务回滚处理过程
    如果创建过保存点,则回滚到上一保存点 
    如果是我发起的,进行回滚
    如果我只是参与已存在事务,并且检测到了本地回滚标志或isGlobalRollbackOnParticipationFailure==true,则设置全局事务回滚。当执行commit请求时,如果检测到shouldCommitOnGlobalRollbackOnly==false,处理回滚;    
   commit方法
   检测到本地回滚标志,进行回滚处理
   检测到shouldCommitOnGlobalRollbackOnly==false&&isGlobalRollbackOnParticipationFailure==true,进行回滚;同时如果是我发起的或者failEarlyOnGlobalRollbackOnly==true,则抛出异常。
   否则进行事务提交处理:释放保存点或者提交事务。之后仍然检测failEarlyOnGlobalRollbackOnly==true抛出异常
   如果提交事务出错
    TransactionException:检测isRollbackOnCommitFailure标志,进行回滚处理
    RuntimeException或Error:进行回滚处理


/**
	 * This implementation of commit handles participating in existing
	 * transactions and programmatic rollback requests.
	 * Delegates to <code>isRollbackOnly</code>, <code>doCommit</code>
	 * and <code>rollback</code>.
	 * @see org.springframework.transaction.TransactionStatus#isRollbackOnly()
	 * @see #doCommit
	 * @see #rollback
	 */
	public final void commit(TransactionStatus status) throws TransactionException {
		if (status.isCompleted()) {
			throw new IllegalTransactionStateException(
					"Transaction is already completed - do not call commit or rollback more than once per transaction");
		}

		DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
		if (defStatus.isLocalRollbackOnly()) {
			if (defStatus.isDebug()) {
				logger.debug("Transactional code has requested rollback");
			}
			processRollback(defStatus);
			return;
		}
		if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {
			if (defStatus.isDebug()) {
				logger.debug("Global transaction is marked as rollback-only but transactional code requested commit");
			}
			processRollback(defStatus);
			// Throw UnexpectedRollbackException only at outermost transaction boundary
			// or if explicitly asked to.
			if (status.isNewTransaction() || isFailEarlyOnGlobalRollbackOnly()) {
				throw new UnexpectedRollbackException(
						"Transaction rolled back because it has been marked as rollback-only");
			}
			return;
		}

		processCommit(defStatus);
	}

/**
	 * Process an actual rollback.
	 * The completed flag has already been checked.
	 * @param status object representing the transaction
	 * @throws TransactionException in case of rollback failure
	 */
	private void processRollback(DefaultTransactionStatus status) {
		try {
			try {
				triggerBeforeCompletion(status);
				if (status.hasSavepoint()) {
					if (status.isDebug()) {
						logger.debug("Rolling back transaction to savepoint");
					}
					status.rollbackToHeldSavepoint();
				}
				else if (status.isNewTransaction()) {
					if (status.isDebug()) {
						logger.debug("Initiating transaction rollback");
					}
					doRollback(status);
				}
				else if (status.hasTransaction()) {
					if (status.isLocalRollbackOnly() || isGlobalRollbackOnParticipationFailure()) {
						if (status.isDebug()) {
							logger.debug("Participating transaction failed - marking existing transaction as rollback-only");
						}
						doSetRollbackOnly(status);
					}
					else {
						if (status.isDebug()) {
							logger.debug("Participating transaction failed - letting transaction originator decide on rollback");
						}
					}
				}
				else {
					logger.debug("Should roll back transaction but cannot - no transaction available");
				}
			}
			catch (RuntimeException ex) {
				triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
				throw ex;
			}
			catch (Error err) {
				triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
				throw err;
			}
			triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
		}
		finally {
			cleanupAfterCompletion(status);
		}
	}

/**
	 * Process an actual commit.
	 * Rollback-only flags have already been checked and applied.
	 * @param status object representing the transaction
	 * @throws TransactionException in case of commit failure
	 */
	private void processCommit(DefaultTransactionStatus status) throws TransactionException {
		try {
			boolean beforeCompletionInvoked = false;
			try {
				prepareForCommit(status);
				triggerBeforeCommit(status);
				triggerBeforeCompletion(status);
				beforeCompletionInvoked = true;
				boolean globalRollbackOnly = false;
				if (status.isNewTransaction() || isFailEarlyOnGlobalRollbackOnly()) {
					globalRollbackOnly = status.isGlobalRollbackOnly();
				}
				if (status.hasSavepoint()) {
					if (status.isDebug()) {
						logger.debug("Releasing transaction savepoint");
					}
					status.releaseHeldSavepoint();
				}
				else if (status.isNewTransaction()) {
					if (status.isDebug()) {
						logger.debug("Initiating transaction commit");
					}
					doCommit(status);
				}
				// Throw UnexpectedRollbackException if we have a global rollback-only
				// marker but still didn't get a corresponding exception from commit.
				if (globalRollbackOnly) {
					throw new UnexpectedRollbackException(
							"Transaction silently rolled back because it has been marked as rollback-only");
				}
			}
			catch (UnexpectedRollbackException ex) {
				// can only be caused by doCommit
				triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
				throw ex;
			}
			catch (TransactionException ex) {
				// can only be caused by doCommit
				if (isRollbackOnCommitFailure()) {
					doRollbackOnCommitException(status, ex);
				}
				else {
					triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
				}
				throw ex;
			}
			catch (RuntimeException ex) {
				if (!beforeCompletionInvoked) {
					triggerBeforeCompletion(status);
				}
				doRollbackOnCommitException(status, ex);
				throw ex;
			}
			catch (Error err) {
				if (!beforeCompletionInvoked) {
					triggerBeforeCompletion(status);
				}
				doRollbackOnCommitException(status, err);
				throw err;
			}

			// Trigger afterCommit callbacks, with an exception thrown there
			// propagated to callers but the transaction still considered as committed.
			try {
				triggerAfterCommit(status);
			}
			finally {
				triggerAfterCompletion(status, TransactionSynchronization.STATUS_COMMITTED);
			}

		}
		finally {
			cleanupAfterCompletion(status);
		}
	}


分享到:
评论

相关推荐

    Spring事务传播机制.docx

    从代码来看,回滚的原因在于,子事务失败的时候在回滚代码中设置了全局回滚的标识(AbstractPlatformTransactionManager.processRollback)。之后主事务在进行事务提交时,会判断全局回滚标识是否存在。若存在就会...

    COS——R.log

    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:626) at org.springframework.transaction.interceptor....

    多数据源事务解决方案,单应用多数据库保证事务

    对于多数据源事务,我们可以使用AbstractPlatformTransactionManager的子类,如DataSourceTransactionManager,它可以处理单个数据源的事务。然而,对于多个数据源,我们需要更复杂的策略,比如使用...

    proxool 多数据源动态切换,刚刚一网友问我,顺便写的一个demo

    在Spring中,如果使用了`@Transactional`注解,需要确保事务管理器能够正确处理多数据源的情况,例如使用`AbstractPlatformTransactionManager`的子类,并在运行时根据数据源选择相应的事务管理策略。 总之,...

    Spring面试题大全

    3. PlatformTransactionManager:这是Spring提供的用于管理事务的基础接口,其下有一个实现的抽象类AbstractPlatformTransactionManager,我们使用的事务管理类例如DataSourceTransactionManager等都是这个类的子类...

    Spring事务原理、Spring事务配置的五种方式

    PlatformTransactionManager是Spring提供的用于管理事务的基础接口,其下有一个实现的抽象类AbstractPlatformTransactionManager。我们使用的事务管理类,例如DataSourceTransactionManager等都是这个类的子类。 ...

    SpringXMLTransaction

    而`AbstractPlatformTransactionManager`是所有事务管理器的抽象基类,具体的事务管理器如`DataSourceTransactionManager`继承自它,实现了事务的开始、提交、回滚等操作。 在标签“工具”下,我们可以理解...

    spring多数据源动态切换方案

    4. 配置事务管理器:由于我们的数据源是动态的,所以需要使用`DataSourceTransactionManager`的子类`AbstractPlatformTransactionManager`。设置transactionManager的dataSource属性为我们之前创建的...

    Spring Boot数据库事务控制.zip

    8. **事务同步**:Spring提供了PlatformTransactionManager接口来管理事务,而AbstractPlatformTransactionManager是其主要实现。通过TransactionTemplate和JdbcTemplate等工具类,我们可以进行事务同步,确保在同一...

    SPRING API 2.0.CHM

    AbstractPlatformTransactionManager AbstractPointcutAdvisor AbstractPoolingServerSessionFactory AbstractPoolingTargetSource AbstractPropertyAccessor AbstractPropertyBindingResult ...

    SpringSourceCodeAnalysis:Spring原始解析视频原始备份

    源码中TransactionProxyFactoryBean和AbstractPlatformTransactionManager等类是关键。 4. **Spring MVC**:Spring的Web MVC框架提供了模型-视图-控制器架构,简化了Web应用的开发。源码分析可以揭示...

Global site tag (gtag.js) - Google Analytics