日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring事务管理(三)-PlatformmTransactionManager解析和事务传播方式原理

發(fā)布時間:2023/12/9 javascript 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring事务管理(三)-PlatformmTransactionManager解析和事务传播方式原理 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

2019獨角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>

Spring在事務(wù)管理時,對事務(wù)的處理做了極致的抽象,即PlatformTransactionManager。對事務(wù)的操作,簡單地來說,只有三步操作:獲取事務(wù),提交事務(wù),回滾事務(wù)。

public interface PlatformTransactionManager {// 獲取事務(wù)TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException;// 提交事務(wù)void commit(TransactionStatus status) throws TransactionException;// 回滾事務(wù)void rollback(TransactionStatus status) throws TransactionException;}

當(dāng)然Spring不會僅僅只提供一個接口,同時會有一個抽象模版類,實現(xiàn)了事務(wù)管理的具體骨架。AbstractPlatformTransactionManager類可以說是Spring事務(wù)管理的控制臺,決定事務(wù)如何創(chuàng)建,提交和回滾。

在Spring事務(wù)管理(二)-TransactionProxyFactoryBean原理中,分析TransactionInterceptor增強時,在invoke方法中最重要的三個操作:

  • 創(chuàng)建事務(wù) createTransactionIfNecessary
  • 異常后事務(wù)處理 completeTransactionAfterThrowing
  • 方法執(zhí)行成功后事務(wù)提交 commitTransactionAfterReturning
  • 在具體操作中,最后都是通過事務(wù)管理器PlatformTransactionManager的接口實現(xiàn)來執(zhí)行的,其實也就是上面列出的三個接口方法。我們分別介紹這三個方法的實現(xiàn),并以DataSourceTransactionManager為實現(xiàn)類觀察JDBC方式事務(wù)的具體實現(xiàn)。

    1. 獲取事務(wù)

    getTransaction方法根據(jù)事務(wù)定義來獲取事務(wù)狀態(tài),事務(wù)狀態(tài)中記錄了事務(wù)定義,事務(wù)對象及事務(wù)相關(guān)的資源信息。對于事務(wù)的獲取,除了調(diào)用事務(wù)管理器的實現(xiàn)來獲取事務(wù)對象本身外,另外的很重要的一點是處理了事務(wù)的傳播方式。

    public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException {// 1.獲取事務(wù)對象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();}// 2.如果已存在事務(wù),根據(jù)不同的事務(wù)傳播方式處理獲取事務(wù)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());}// 3. 如果當(dāng)前沒有事務(wù),不同的事務(wù)傳播方式不同處理方式// 3.1 事務(wù)傳播方式為mandatory(強制必須有事務(wù)),則拋出異常// 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'");}// 3.2 事務(wù)傳播方式為required或required_new或nested(嵌套),創(chuàng)建一個新的事務(wù)狀態(tài)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);// 創(chuàng)建新的事務(wù)狀態(tài)對象DefaultTransactionStatus status = newTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);// 事務(wù)初始化doBegin(transaction, definition);// 準(zhǔn)備其他同步操作prepareSynchronization(status, definition);return status;}catch (RuntimeException | Error ex) {resume(null, suspendedResources);throw ex;}}// 3.3 其他事務(wù)傳播方式,返回一個事務(wù)對象為null的事務(wù)狀態(tài)對象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);} }

    獲取事務(wù)的方法主要做兩件事情:

  • 獲取事務(wù)對象
  • 根據(jù)事務(wù)傳播方式返回事務(wù)狀態(tài)對象
  • 獲取事務(wù)對象,在DataSourceTransactionManager的實現(xiàn)中,返回一個DataSourceTransactionObject對象

    protected Object doGetTransaction() {DataSourceTransactionObject txObject = new DataSourceTransactionObject();txObject.setSavepointAllowed(isNestedTransactionAllowed());ConnectionHolder conHolder =(ConnectionHolder) // 從事務(wù)同步管理器中根據(jù)DataSource獲取數(shù)據(jù)庫連接資源 TransactionSynchronizationManager.getResource(obtainDataSource());txObject.setConnectionHolder(conHolder, false);return txObject; }

    每次執(zhí)行doGetTransaction方法,即會創(chuàng)建一個DataSourceTransactionObject對象txObject,并從事務(wù)同步管理器中根據(jù)DataSource獲取數(shù)據(jù)庫連接持有對象ConnectionHolder,然后存入txObject中。**事務(wù)同步管理類持有一個ThreadLocal級別的resources對象,存儲DataSource和ConnectionHolder的映射關(guān)系。**因此返回的txObject中持有的ConnectionHolder可能有值,也可能為空。而不同的事務(wù)傳播方式下,事務(wù)管理的處理根據(jù)txObejct中是否存在事務(wù)有不同的處理方式。

    關(guān)于關(guān)注事務(wù)傳播方式的實現(xiàn),很多人對事務(wù)傳播方式都是一知半解,只是因為沒有了解源碼的實現(xiàn)。現(xiàn)在就來看看具體的實現(xiàn)。事務(wù)傳播方式的實現(xiàn)分為兩種情況,事務(wù)不存在和事務(wù)已經(jīng)存在。isExistingTransaction方法判斷事務(wù)是否存在,默認(rèn)在AbstractPlatformTransactionManager抽象類中返回false,而在DataSourceTransactionManager實現(xiàn)中,則根據(jù)是否有數(shù)據(jù)庫連接來決定。

    protected boolean isExistingTransaction(Object transaction) {DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;return (txObject.hasConnectionHolder() && txObject.getConnectionHolder().isTransactionActive()); }

    當(dāng)前無事務(wù)

    如果當(dāng)前沒有事務(wù),則不同事務(wù)傳播方式的處理如下:

  • 事務(wù)傳播方式為mandatory(強制必須有事務(wù)),當(dāng)前沒有事務(wù),即拋出異常。
  • 事務(wù)傳播方式為required或required_new或nested(嵌套),當(dāng)前沒有事務(wù),即會創(chuàng)建一個新的事務(wù)狀態(tài)。
  • 其他事務(wù)傳播方式時,直接返回事務(wù)對象為null的事務(wù)狀態(tài)對象,即不在事務(wù)中執(zhí)行。
  • 如何創(chuàng)建一個新的事務(wù)狀態(tài)

    // 1. 新建事務(wù)狀態(tài),返回DefaultTransactionStatus對象 DefaultTransactionStatus status = newTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, suspendedResources); // 2. 事務(wù)初始化 doBegin(transaction, definition); // 3. 準(zhǔn)備同步操作 prepareSynchronization(status, definition); return status;

    第一步,新建事務(wù)狀態(tài),就是構(gòu)建一個DefaultTransactionStatus對象

    protected DefaultTransactionStatus newTransactionStatus(TransactionDefinition definition, @Nullable Object transaction, boolean newTransaction,boolean newSynchronization, boolean debug, @Nullable Object suspendedResources) {boolean actualNewSynchronization = newSynchronization &&!TransactionSynchronizationManager.isSynchronizationActive();return new DefaultTransactionStatus(transaction, newTransaction, actualNewSynchronization,definition.isReadOnly(), debug, suspendedResources); }

    第二步,事務(wù)初始化,AbstractPlatformTransactionManager沒有實現(xiàn),來看DataSourceTransactionManager的實現(xiàn):獲取一個新的數(shù)據(jù)庫連接并開啟事務(wù),完成事務(wù)的基本屬性設(shè)置。

    protected void doBegin(Object transaction, TransactionDefinition definition) {DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;Connection con = null;try {// 如果當(dāng)前沒有事務(wù),由DataSource獲取一個新的數(shù)據(jù)庫連接,并賦予txObjectif (!txObject.hasConnectionHolder() ||txObject.getConnectionHolder().isSynchronizedWithTransaction()) {Connection newCon = obtainDataSource().getConnection();if (logger.isDebugEnabled()) {logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");}txObject.setConnectionHolder(new ConnectionHolder(newCon), true);}// 設(shè)置數(shù)據(jù)庫連接與事務(wù)同步txObject.getConnectionHolder().setSynchronizedWithTransaction(true);con = txObject.getConnectionHolder().getConnection();// 設(shè)置事務(wù)隔離級別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).// 非常重要的一點,JDBC通過設(shè)置自動提交為false,開啟一個新的事務(wù)if (con.getAutoCommit()) {txObject.setMustRestoreAutoCommit(true);if (logger.isDebugEnabled()) {logger.debug("Switching JDBC Connection [" + con + "] to manual commit");}con.setAutoCommit(false);}// 如果設(shè)置事務(wù)只讀屬性,執(zhí)行Statement設(shè)置只讀prepareTransactionalConnection(con, definition);// 激活事務(wù)狀態(tài)txObject.getConnectionHolder().setTransactionActive(true);// 設(shè)置超時時間int timeout = determineTimeout(definition);if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {txObject.getConnectionHolder().setTimeoutInSeconds(timeout);}// Bind the connection holder to the thread.// 如果為新連接,綁定DataSource和數(shù)據(jù)庫連接持有者的映射關(guān)系if (txObject.isNewConnectionHolder()) {TransactionSynchronizationManager.bindResource(obtainDataSource(), txObject.getConnectionHolder());}}catch (Throwable ex) {if (txObject.isNewConnectionHolder()) {DataSourceUtils.releaseConnection(con, obtainDataSource());txObject.setConnectionHolder(null, false);}throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);} }

    第三步:準(zhǔn)備同步操作,如果事務(wù)狀態(tài)開啟同步,則在事務(wù)同步管理器中設(shè)置事務(wù)基礎(chǔ)屬性

    protected void prepareSynchronization(DefaultTransactionStatus status, TransactionDefinition definition) {if (status.isNewSynchronization()) {TransactionSynchronizationManager.setActualTransactionActive(status.hasTransaction());TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT ?definition.getIsolationLevel() : null);TransactionSynchronizationManager.setCurrentTransactionReadOnly(definition.isReadOnly());TransactionSynchronizationManager.setCurrentTransactionName(definition.getName());TransactionSynchronizationManager.initSynchronization();} }

    當(dāng)前有事務(wù)

    如果當(dāng)前已經(jīng)有事務(wù)存在,由handleExistingTransaction方法完成事務(wù)操作。

  • 傳播方式為never(不允許事務(wù)),拋出異常
  • 傳播方式為not_supported(不支持),則掛起當(dāng)前事務(wù),以無事務(wù)方式運行
  • 傳播方式為required_new,掛起原有事務(wù),并開啟新的事務(wù)
  • 傳播方式為nested(嵌套),創(chuàng)建嵌套事務(wù)。這里一般方式都是通過savepoint保存點的完成嵌套,但Spring對JTA事務(wù)單獨做了另一種處理。
  • 傳播方式為supports或required,返回當(dāng)前事務(wù)
  • private TransactionStatus handleExistingTransaction(TransactionDefinition definition, Object transaction, boolean debugEnabled)throws TransactionException {// 傳播方式為never(不允許事務(wù)),拋出異常if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {throw new IllegalTransactionStateException("Existing transaction found for transaction marked with propagation 'never'");}// 傳播方式為not_supported(不支持),則掛起當(dāng)前事務(wù),以無事務(wù)方式運行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);}// 傳播方式為required_new,掛起原有事務(wù),并開啟新的事務(wù)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 | Error beginEx) {resumeAfterBeginException(transaction, suspendedResources, beginEx);throw beginEx;}}// 傳播方式為nested(嵌套),創(chuàng)建嵌套事務(wù)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() + "]");}// 使用保存點支持嵌套事務(wù)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;}// 只適用于JTA事務(wù):通過嵌套的begin和commit/rollback創(chuàng)建嵌套事務(wù)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.// 傳播方式為supports或required,返回當(dāng)前事務(wù)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); }

    這里關(guān)注兩個點

    第一是事務(wù)的掛起,Spring并不是真的對數(shù)據(jù)庫連接做了什么掛起操作,而是在邏輯上由事務(wù)同步管理器做了事務(wù)信息和狀態(tài)的重置,并將原事務(wù)信息和狀態(tài)返回,并記錄在新的事務(wù)狀態(tài)對象中,從而形成一種鏈?zhǔn)浇Y(jié)構(gòu)。

    protected final SuspendedResourcesHolder suspend(@Nullable Object transaction) throws TransactionException {if (TransactionSynchronizationManager.isSynchronizationActive()) {List<TransactionSynchronization> suspendedSynchronizations = doSuspendSynchronization();try {Object suspendedResources = null;if (transaction != null) {suspendedResources = doSuspend(transaction);}String name = TransactionSynchronizationManager.getCurrentTransactionName();TransactionSynchronizationManager.setCurrentTransactionName(null);boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();TransactionSynchronizationManager.setCurrentTransactionReadOnly(false);Integer isolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(null);boolean wasActive = TransactionSynchronizationManager.isActualTransactionActive();TransactionSynchronizationManager.setActualTransactionActive(false);return new SuspendedResourcesHolder(suspendedResources, suspendedSynchronizations, name, readOnly, isolationLevel, wasActive);}catch (RuntimeException | Error ex) {// doSuspend failed - original transaction is still active...doResumeSynchronization(suspendedSynchronizations);throw ex;}}else if (transaction != null) {// Transaction active but no synchronization active.Object suspendedResources = doSuspend(transaction);return new SuspendedResourcesHolder(suspendedResources);}else {// Neither transaction nor synchronization active.return null;} }

    第二是嵌套事務(wù)設(shè)置保存點,通常由JDBC3.0支持的savepoint API完成,然后將保存點記錄在事務(wù)狀態(tài)中。

    DefaultTransactionStatus status =prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null); status.createAndHoldSavepoint(); return status;

    至此,完成了獲取事務(wù)

    2.提交事務(wù)

    首先要說的,commit方法并不是一定提交事務(wù),也可能回滾。

    public final void commit(TransactionStatus status) throws TransactionException {// 事務(wù)已經(jīng)提交,再次提交拋出異常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;// 如果事務(wù)狀態(tài)設(shè)置了回滾標(biāo)識,則執(zhí)行回滾if (defStatus.isLocalRollbackOnly()) {if (defStatus.isDebug()) {logger.debug("Transactional code has requested rollback");}processRollback(defStatus, false);return;}// 設(shè)置全局回滾標(biāo)識為true,則執(zhí)行回滾if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {if (defStatus.isDebug()) {logger.debug("Global transaction is marked as rollback-only but transactional code requested commit");}processRollback(defStatus, true);return;}// 提交事務(wù)processCommit(defStatus); }

    processCommit執(zhí)行事務(wù)的提交,但事務(wù)的提交也分為幾種情況:

  • 存在保存點,即嵌套事務(wù),則釋放保存點
  • 如果事務(wù)是由當(dāng)前事務(wù)狀態(tài)開啟的,即事務(wù)傳播的第一層,執(zhí)行事務(wù)提交
  • 其他情況(比如事務(wù)是繼承自上一層),則不做任何操作
  • 且在processCommit方法中,不同時候設(shè)置了不同狀態(tài)的觸發(fā)監(jiān)控,用來提示事務(wù)同步相關(guān)資源,觸發(fā)需要的操作。

    private void processCommit(DefaultTransactionStatus status) throws TransactionException {try {boolean beforeCompletionInvoked = false;try {boolean unexpectedRollback = false;prepareForCommit(status);// 提交前提示triggerBeforeCommit(status);// 完成前提示triggerBeforeCompletion(status);beforeCompletionInvoked = true;if (status.hasSavepoint()) {if (status.isDebug()) {logger.debug("Releasing transaction savepoint");}unexpectedRollback = status.isGlobalRollbackOnly();status.releaseHeldSavepoint();}else if (status.isNewTransaction()) {if (status.isDebug()) {logger.debug("Initiating transaction commit");}unexpectedRollback = status.isGlobalRollbackOnly();// 執(zhí)行事務(wù)提交doCommit(status);}else if (isFailEarlyOnGlobalRollbackOnly()) {unexpectedRollback = status.isGlobalRollbackOnly();}// Throw UnexpectedRollbackException if we have a global rollback-only// marker but still didn't get a corresponding exception from commit.if (unexpectedRollback) {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 doCommitif (isRollbackOnCommitFailure()) {doRollbackOnCommitException(status, ex);}else {// 未知狀態(tài)完成提示triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);}throw ex;}catch (RuntimeException | Error ex) {if (!beforeCompletionInvoked) {triggerBeforeCompletion(status);}doRollbackOnCommitException(status, ex);throw ex;}// Trigger afterCommit callbacks, with an exception thrown there// propagated to callers but the transaction still considered as committed.try {// 事務(wù)提交完成提示triggerAfterCommit(status);}finally {// 操作完成完成提示triggerAfterCompletion(status, TransactionSynchronization.STATUS_COMMITTED);}}finally {// 完成后清理cleanupAfterCompletion(status);} }

    DataSourceTransactionManager對doCommit的實現(xiàn),就是執(zhí)行數(shù)據(jù)庫連接的提交

    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 {// 提交事務(wù)con.commit();}catch (SQLException ex) {throw new TransactionSystemException("Could not commit JDBC transaction", ex);} }

    3.回滾事務(wù)

    回滾事務(wù)時也分為幾種情況:

  • 存在保存點(嵌套事務(wù)),則回滾到保存點
  • 如果事務(wù)是由當(dāng)前事務(wù)狀態(tài)開啟的,則執(zhí)行回滾操作
  • 其他情況下,如果事務(wù)狀態(tài)設(shè)置了回滾標(biāo)識,則設(shè)置事務(wù)對象的狀態(tài)也為回滾,否則不做任何操作
  • private void processRollback(DefaultTransactionStatus status, boolean unexpected) {try {boolean unexpectedRollback = unexpected;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");}// 回滾事務(wù)doRollback(status);}else {// Participating in larger transactionif (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");}// Unexpected rollback only matters here if we're asked to fail earlyif (!isFailEarlyOnGlobalRollbackOnly()) {unexpectedRollback = false;}}}catch (RuntimeException | Error ex) {triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);throw ex;}triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);// Raise UnexpectedRollbackException if we had a global rollback-only markerif (unexpectedRollback) {throw new UnexpectedRollbackException("Transaction rolled back because it has been marked as rollback-only");}}finally {cleanupAfterCompletion(status);} }

    對于DataSourceTransactionManager實現(xiàn),回滾保存點和回滾事務(wù)都由JDBC的API來完成。

    至此,事務(wù)管理器對事務(wù)的三種操作就簡單地介紹完了,但其中事務(wù)同步資源的控制十分精妙,這里就不做詳細(xì)的介紹。有興趣的自己去研究源碼。于我而言,任何強大的機制都是由一行行地源碼精妙地組建出來的,深入進(jìn)去,一切都將真相大白。

    轉(zhuǎn)載于:https://my.oschina.net/u/2377110/blog/1614198

    總結(jié)

    以上是生活随笔為你收集整理的Spring事务管理(三)-PlatformmTransactionManager解析和事务传播方式原理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。