亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

spring事務之事務掛起和事務恢復源碼解讀

 更新時間:2022年11月21日 11:01:25   作者:小小少年_  
這篇文章主要介紹了spring事務之事務掛起和事務恢復源碼解讀,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

事務掛起和事務恢復源碼解讀

在學習spring事務的時候,一定會涉及到一個概念,無法避免的,就是事務掛起和事務恢復

對于事務掛起和事務恢復,可以簡單的描述一下,是這樣的

  • 1.首先我們假設有兩個類,A類和B類,兩個類中的字段是一模一樣的,A類表示當前事務,B類表示備份事務
  • 2.如果我開啟一個事務,會把當前事務信息,存入到A類中,如果我這時候要進行事務掛起
  • 3.事務掛起:就會把A類中當前事務的信息,賦值到B類中,然后在創(chuàng)建一個新事務的時候,會賦值到A類中
  • 4.恢復事務:如果此時我當前事務執(zhí)行完畢了,需要恢復原來的事務,就只需要將A類清空,然后將B類中的數(shù)據(jù)信息賦值到A類,此時A事務就會再次生效

我覺得可以理解為就是倒騰了一手

事務掛起源碼

org.springframework.transaction.support.AbstractPlatformTransactionManager#handleExistingTransaction

我們直接跳入到這個方法中來看,這個方法是在當前事務存在的時候,會進入到這個方法來處理,執(zhí)行鏈路是這樣的

org.springframework.transaction.interceptor.TransactionInterceptor#invoke
    org.springframework.transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction
        org.springframework.transaction.interceptor.TransactionAspectSupport#createTransactionIfNecessary
            org.springframework.transaction.support.AbstractPlatformTransactionManager#getTransaction
                org.springframework.transaction.support.AbstractPlatformTransactionManager#handleExistingTransaction

正常的話,一個事務方法的執(zhí)行是這個鏈路,自己debug看下即可,但是要進入到這個方法中,有一個前提,就是當前事務已存在,然后又調(diào)用了另外一個事務方法,才會進入到這里

我們以PROPAGATION_REQUIRES_NEW這個級別的傳播機制為例,為什么以這個為例,因為這個傳播機制,在當前事務存在的時候,是會將當前事務掛起,然后開啟一個新的事務,也正好可以看下spring是如何掛起事務,并創(chuàng)建新事務的

if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
	if (debugEnabled) {
		logger.debug("Suspending current transaction, creating new transaction with name [" +
				definition.getName() + "]");
	}
	/**
	 * 這里是掛起事務的操作,掛起事務的話,會把事務管理器中的屬性設置為null
	 * ,然后將事務管理器中的屬性暫時存儲到suspendedResourceHolder中
	 */
	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) {
		/**
		 * 如果在開啟新的事務的時候,異常了,就會在下面這個方法中,將事務恢復(和上面掛起是相對的)
		 * ,其實就是把suspendResourceHolder中的屬性重新賦值到TransactionSynchronizationManager
		 */
		resumeAfterBeginException(transaction, suspendedResources, beginEx);
		throw beginEx;
	}
}

由于這個方法中,代碼比較多,我就刪減了一部分,只留下了propagation_requires_new這個傳播機制的代碼

可以看到,會先調(diào)用suspend(transaction)將當前事務掛起,然后再下面的doBegin()再開啟一個新的事務,然后通過prepareSynchronization(),將事務相關信息放入到threadLocal中

suspend(transaction)

/**
* 這是掛起事務的源碼
 * 所謂的事務掛起:就是將當前事務管理器中的相關屬性,保存到suspendedResourceHolder中
 */
@Nullable
protected final SuspendedResourcesHolder suspend(@Nullable Object transaction) throws TransactionException {
	/**
	 * 1.如果當前事務是active狀態(tài),就將事務掛起,掛起的操作其實也簡單
	 * 將當前事務的屬性信息暫存到SuspendedResourcesHolder中,然后將當前事務的屬性設置為null
	 */
	if (TransactionSynchronizationManager.isSynchronizationActive()) {
		List<TransactionSynchronization> suspendedSynchronizations = doSuspendSynchronization();
		try {
			Object suspendedResources = null;
			if (transaction != null) {
				suspendedResources = doSuspend(transaction);
			}
			/**
			 * 1.1 下面就是掛起事務的操作,將事務同步管理器中的屬性置為null
			 * , 然后將配置信息,存儲到suspendedResources中,以便在恢復事務的時候,可以恢復
			 */
			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) {
			/**
			 * 2.如果掛起事務失敗,就需要進行回滾,就是將suspendedResourcesHolder
			 * 中的屬性重新賦值到TransactionSynchronizationManager中
			 */
			// 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;
	}
}

這是suspend的源碼,可以看到,在1.1這個注釋位置,會獲取到當前事務的屬性信息,然后在下面,會new SuspendedResourcesHolder(),將當前事務屬性信息放入到這里面

再下面,就是一些異常的判斷和處理,我們可以認為,這個方法就是把事務的屬性信息存入到了SuspendedResourcesHolder對象中

newTransactionStatus()

這個方法也很重要,會把剛才創(chuàng)建的suspend對象,放入到DefaultTransactionStatus類中,這里我猜是為了在后面事務恢復的時候用的

doBegin()

在doBegin()方法中,主要是重新獲取一個數(shù)據(jù)庫連接,然后設置連接的相關信息,比如:非自動提交等

然后將連接信息存入到TransactionSynchronizationManager對象中

我們可以簡單認為doBegin()就是重新開啟了一個事務連接

事務恢復

前面講的是事務掛起,下面來說事務恢復,事務恢復,就是在事務提交或者回滾的時候,會進行事務恢復的處理


這里直接貼了一張圖,是事務提交和事務回滾的處理流程,最終都會調(diào)用到cleanupAfterCompletion()方法,這個方法就是事務恢復的代碼

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");
			}
			Object transaction = (status.hasTransaction() ? status.getTransaction() : null);
			resume(transaction, (SuspendedResourcesHolder) status.getSuspendedResources());
		}
	}

在這個代碼中,前面是一些邏輯處理,應該是對當前事務進行清除的操作,需要關注的是最后一行代碼,resume()方法

protected final void resume(@Nullable Object transaction, @Nullable SuspendedResourcesHolder resourcesHolder)
			throws TransactionException {

		if (resourcesHolder != null) {
			Object suspendedResources = resourcesHolder.suspendedResources;
			if (suspendedResources != null) {
				doResume(transaction, suspendedResources);
			}
			List<TransactionSynchronization> suspendedSynchronizations = resourcesHolder.suspendedSynchronizations;
			if (suspendedSynchronizations != null) {
				TransactionSynchronizationManager.setActualTransactionActive(resourcesHolder.wasActive);
				TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(resourcesHolder.isolationLevel);
				TransactionSynchronizationManager.setCurrentTransactionReadOnly(resourcesHolder.readOnly);
				TransactionSynchronizationManager.setCurrentTransactionName(resourcesHolder.name);
				doResumeSynchronization(suspendedSynchronizations);
			}
		}
	}

這里可以看到,是從resourcesHolder中取一些參數(shù)賦值到TransactionSynchronizationManager中;SuspendedResourcesHolder是哪個對象呢?

就是前面事務掛起的時候,將當前事務參數(shù)信息賦值到的一個對象

所以

我們可以認為,事務掛起就是將事務賦值到一個臨時對象中,事務恢復就是從臨時對象中,將事務屬性信息賦值到當前事務中

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • Java多線程中線程間的通信實例詳解

    Java多線程中線程間的通信實例詳解

    這篇文章主要介紹了Java多線程中線程間的通信實例詳解的相關資料,需要的朋友可以參考下
    2017-04-04
  • 徹底搞懂Java多線程(二)

    徹底搞懂Java多線程(二)

    這篇文章主要給大家介紹了關于Java面試題之多線程和高并發(fā)的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用java具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2021-07-07
  • 100行java寫的微信跳一跳輔助程序

    100行java寫的微信跳一跳輔助程序

    本篇文章給大家分享了用java寫的一個微信跳一跳輔助腳本程序,有興趣的朋友參考學習下。
    2018-01-01
  • Java中keytool的使用

    Java中keytool的使用

    Keytool 是一個JAVA環(huán)境下的安全鑰匙與證書的管理工具,Keytool將密鑰(key)和證書(certificates)存在一個稱為keystore 的文件(受密碼保護)中,本文重點給大家介紹keytool的使用,感興趣的朋友一起看看吧
    2022-02-02
  • Spring Boot整合Spring Security簡單實現(xiàn)登入登出從零搭建教程

    Spring Boot整合Spring Security簡單實現(xiàn)登入登出從零搭建教程

    這篇文章主要給大家介紹了關于Spring Boot整合Spring Security簡單實現(xiàn)登入登出從零搭建的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起看看吧
    2018-09-09
  • Java動態(tài)代理語法Proxy類原理詳解

    Java動態(tài)代理語法Proxy類原理詳解

    這篇文章主要介紹了Java動態(tài)代理語法Proxy類原理詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-04-04
  • JavaWeb詳細講述Cookie和Session的概念

    JavaWeb詳細講述Cookie和Session的概念

    web開發(fā)階段我們主要是瀏覽器和服務器之間來進行交互。瀏覽器和服務器之間的交互就像人和人之間進行交流一樣,但是對于機器來說,在一次請求之間只是會攜帶著本次請求的數(shù)據(jù)的,但是可能多次請求之間是會有聯(lián)系的,所以提供了會話機制
    2022-06-06
  • Java遞歸模糊查詢文件實例代碼

    Java遞歸模糊查詢文件實例代碼

    遞歸算法是一種直接或間接地調(diào)用自身的算法,在計算機編寫程序中,遞歸算法對解決一大類問題是十分有效的,它往往使算法的描述簡潔而且易于理解,這篇文章主要給大家介紹了關于Java遞歸模糊查詢文件的相關資料,需要的朋友可以參考下
    2021-11-11
  • 淺析Java中關鍵詞volatile底層的實現(xiàn)原理

    淺析Java中關鍵詞volatile底層的實現(xiàn)原理

    在 Java 并發(fā)編程中,有 3 個最常用的關鍵字:synchronized、ReentrantLock 和 volatile,這篇文章主要來和大家聊聊volatile底層的實現(xiàn)原理,感興趣的可以了解下
    2024-02-02
  • Java基于JDBC實現(xiàn)事務,銀行轉(zhuǎn)賬及貨物進出庫功能示例

    Java基于JDBC實現(xiàn)事務,銀行轉(zhuǎn)賬及貨物進出庫功能示例

    這篇文章主要介紹了Java基于JDBC實現(xiàn)事務,銀行轉(zhuǎn)賬及貨物進出庫功能,較為詳細的分析了事務操作的原理、實現(xiàn)方法及java基于jdbc連接數(shù)據(jù)庫實現(xiàn)銀行事務操作的相關技巧,需要的朋友可以參考下
    2017-12-12

最新評論