1. 程式人生 > >【面試】足夠“忽悠”面試官的『Spring事務管理器』原始碼閱讀梳理(建議珍藏)

【面試】足夠“忽悠”面試官的『Spring事務管理器』原始碼閱讀梳理(建議珍藏)

PS:文章內容涉及原始碼,請耐心閱讀。

 

 

理論實踐,相輔相成



偉大領袖毛主席告訴我們實踐出真知。這是無比正確的。但是也會很辛苦。

就像淘金一樣,從大量沙子中淘出金子一定是一個無比艱辛的過程。但如果真能淘出來,也一定是像金子一樣寶貴的東西。

他老人家還說過,當真知上升為理論的時候,就可以反過來指導實踐了。

在當下這個時代,前輩們已經發現和整理了很多理論,我們直接拿來使用就行了。“拿來主義”不全是不好的。

如果說閱讀原始碼算一種實踐的話,那我們拿什麼“理論”來指導它呢?


兵馬未動,糧草先行

 


答案自然是官方文件。官方文件就是前輩們總結出來的“理論”,一般來說包含三方面的內容:


a)哲學方面:一些設計思想,比如初衷啊、靈感來源啊這些。一些取捨的選擇,比如主要是為了克服什麼痛點、解決什麼問題。

b)詳細解說:把整體內容一點一點的講清楚,包括很多名字解釋,很多設計原理,還有很多注意事項等。

c)入門示例:一些簡單的常規使用例子。


下面我們就來熟悉下這些“理論”的關鍵部分:

事務的執行是和執行緒相關的,那是不是就要使用ThreadLocal來儲存一些相關東西,究竟會儲存哪些東西呢。

物理事務就是到資料庫的一個物理連結,這個連結一開始是如何建立,建立好後又是如何儲存起來呢。

邏輯事務就是一個帶有事務註解的方法,它需要關聯到一個物理事務上。那它是不是先從當前上下文尋找物理事務,找到就用,否則就新開一個物理事務呢。


多個邏輯事務可以對映到一個物理事務上,邏輯事務是各自提交的,如何處理邏輯事務提交和物理事務提交間的關係呢,至少所有的邏輯事務都提交了才可以提交物理事務。

獲取事務時的引數叫事務定義,是一個介面,那它的實現類是哪個,都會包含哪些內容呀,至少要包含事務註解裡指定的內容吧。

獲取事務時的結果叫事務狀態,是一個介面,那它的實現類是哪個,都會包含哪些內容呀。

獲取事務這個方法是非常核心的方法,入參和出參分別是事務定義和事務狀態。你會不會感到有些奇怪,獲取事務的結果不應該是一個事務嗎,為啥卻是一個事務狀態呢?到底有沒有一個類和事務這兩個字對應呢?

多個邏輯事務也可以對映到多個物理事務上,此時就會遇到在當下已存在物理事務的時候再開啟新的物理事務。那麼就需要將當下事務掛起,具體的掛起會執行哪些操作呢。

掛起的事務會存到那裡呢,在新的物理事務提交完畢後又如何將掛起的事務恢復呢。

以上這些問題在你多次閱讀文件和思考後會自動出現的,那我們就帶著這些問題去原始碼中尋找答案。


冥冥之中,早已註定



就像上篇文章中說的,原始碼閱讀找到入口點非常重要。這裡的入口點自然就是事務管理器了。如下圖:

 


這個介面很重要但卻非常簡單,就三個方法,獲取事務/提交/回滾。但它的實現卻相對比較複雜,也讓我們認識到,介面的定義是一個抽象的事情,可以不用考慮實現。

它的一個抽象實現類就是AbstractPlatformTransactionManager,這個類實現了事務管理的整個邏輯關係流程,但是把涉及和具體事務打交道的東西又定義為抽象方法讓子類去實現。

那麼對應於單個數據庫事務的具體實現類就是DataSourceTransactionManager,這個類會完成這些和事務相關的具體的操作。

獲取事務方法的整體執行流程如下:

 

 

 

1、呼叫doGetTransaction()方法從當前上下文中獲取事務物件transaction。

2、如果事務已經存在:

2.1、如果此時事務傳播特性是NEVER,則丟擲異常。

2.2、如果此時事務的傳播特性是NOT_SUPPORTED,則呼叫suspend(transaction)掛起當前事務,將被掛起的資源suspendedResources放入事務狀態裡。

2.3、如果此時事務狀態是REQUIRES_NEW,則呼叫suspend(transaction)掛起當前事務,將事務物件transaction和被掛起的資源suspendedResources放入事務狀態裡。然後呼叫doBegin(transaction, definition)方法去真正開啟事務。最後呼叫prepareSynchronization(status, definition)方法準備一下事務同步。

2.4、如果此時事務的傳播特性是NESTED,又分三種情況:

2.4.1、如果不允許巢狀事務,直接丟擲異常。

2.4.2、如果使用儲存點(Savepoint)來實現巢狀事務,那直接使用當前事務,建立一個儲存點就可以了。

2.4.3、如果使用新的事務來實現巢狀事務,那就呼叫doBegin(transaction, definition)開啟新的事務,此時不需要掛起當前事務。


2.5、對於剩下三種傳播特性REQUIRED/MANDATORY/SUPPORTS,則不需要建立新事務,直接使用當前事務就可以了。

3、如果事務不存在:

3.1、如果此時事務的傳播特性是MANDATORY,則會丟擲異常。

3.2、如果此時事務的傳播特性是REQUIRED/REQUIRES_NEW/NESTED,則呼叫suspend(null)掛起當前事務,將事務物件transaction和被掛起的資源suspendedResources都放入事務狀態裡。然後呼叫doBegin(transaction, definition)方法去真正開啟事務。最後呼叫prepareSynchronization(status, definition)方法準備一下事務同步。

3.3、對於剩下的三種傳播特性SUPPORTS/NOT_SUPPORTED/NEVER,則不需要操作事務。


獲取事務物件的方法如下圖:

 

 

一共有三個關注點:

1、事務物件,即和事務這兩個字對應的那個類。DataSourceTransactionObject從類名來看就是採用資料來源實現的事務物件。下面是它的欄位:

 

 

 

可以看到這個事務物件最主要的作用就是儲存了一個ConnectionHolder物件。

2、使用DataSource物件獲取一個ConnectionHolder物件,從哪裡獲取呢?自然是當前執行的上下文,即ThreadLocal裡了。如下圖:

 

 

此圖中有三點需要注意:

2.1、事務性資源是儲存在Map<Object, Object>裡,key就是DataSource物件,value就是ConnectionHolder物件。

2.2、事務同步這個集合Set<TransactionSynchronization>(圖中黑色線框那個)只有在多個數據源的分散式事務時才使用。

2.3、剩下的是四個和事務相關的變數,事務名稱/是否只讀/隔離級別/是否啟用。


3、將上一步獲取的ConnectionHolder物件(也可能是null)放入事務物件中。


請看ConnectionHolder的定義,如下圖:

 

 

 

主要關注兩點:

一是它包含一個數據庫連結(Connection),因此可以認為它就是表示一個物理事務。

二是它包含一個引用計數(referenceCount),來指示它被引用次數,表示當前有多少個邏輯事務關聯到它(在單資料來源時並沒有使用該欄位)。

 

接著是判斷一個事務是否已存在,如下圖:

 

 

即事務物件要關聯到一個物理事務(即有一個ConnectionHolder物件),同時物理事務還必須是活動的。

那麼在首次執行時,事務肯定是不存在的,因為從執行緒的ThreadLocal裡沒有取出ConnectionHolder物件。那就新開一個事務唄,不過首先要看一下如何掛起一個事務。

掛起事務,如下圖:

 

 

分三種情況:


1、事務同步是活動的,即物理事務已經被繫結到執行緒:

1.1、doSuspendSynchronization()方法返回的List是空的(多資料來源分散式事務時才不為空)

1.2、doSuspend(transaction)去掛起當前事務。

1.3、從ThreadLocal裡取出值,並同時清空ThreadLocal。

1.4、將這些值儲存在SuspendedResourcesHolder類中,表示這些都是被掛起的資源。


2、物理事務是活動的,但是還沒有繫結到執行緒,此時只需掛起事務就行了。

3、沒有物理事務,什麼都不做,返回null即可。


具體的掛起事務操作,請看下圖:

 

 

包括兩步:

相關推薦

面試足夠忽悠面試Spring事務管理原始碼閱讀梳理建議珍藏

PS:文章內容涉及原始碼,請耐心閱讀。     理論實踐,相輔相成 偉大領袖毛主席告訴我們實踐出真知。這是無比正確的。但是也會很辛苦。就像淘金一樣,從大量沙子中淘出金子一定是一個無比艱辛的過程。但如果真能淘出來,也一定是像金子一樣寶貴的東西。他老人家還說過,當真知上升為理論的時候

關於TransactionScope出錯:“與基礎事務管理的通訊失敗”的解決方法

異常資訊: System.Transactions.TransactionManagerCommunicationException: 與基礎事務管理器的通訊失敗。 ---> System.Runtime.InteropServices.COMException: 由

面試Spring事務面試考點吐血整理建議珍藏

Spring和事務的關係 關係型資料庫、某些訊息佇列等產品或中介軟體稱為事務性資源,因為它們本身支援事務,也能夠處理事務。 S

LOJ #2130. 「NOI2015」軟件包管理

stdin mes con 題解 build clas hang AR pair 題解 連樹剖我都寫跪一次,我現在怎麽那麽老年啊= = 簡直滾粗預定了啊。。 我們線段樹維護樹剖只需要資瓷區間覆蓋和區間求和就好了 安裝的時候看看自己到根有多少包裝了,dep減去這個數量就好 卸

JavaScript在全屏或指定區域範圍內尋找指定圖片的座標找圖

原型: seekImage(imageName)  seekImage(imageName, sim) seekImage(topLeftX, topLeftY, bottomRightX, bottomRightY, imageName) seekImage(topLeftX, to

在VS2010上使用C#呼叫非託管C++生成的DLL檔案圖文講解

原文:http://www.cyqdata.com/cnblogs/article-detail-35876# 背景       在專案過程中,有時候你需要呼叫非C#編寫的DLL檔案,尤其在使用一些第三方通訊元件的時候,通過C#來開發應用軟體時,就需要利用

SpringMVC非同步傳送表單資料到JavaBean,並響應JSON文字返回十七

  1) 提交表單後,將JavaBean資訊以JSON文字形式返回到瀏覽器 bean2json.jsp <form> 編號:<input type="text" name="id"

原創中文分詞系統 ICTCLAS2015 的JAVA封裝和多執行緒執行附程式碼

  本文針對的問題是 ICTCLAS2015 的多執行緒分詞,為了實現多執行緒做了簡單的JAVA封裝。如果有需要可以自行進一步封裝其它介面。   首先ICTCLAS2015的傳送門(http://ictclas.nlpir.org/),其對中文分詞做的比較透徹,而且有一定的可調式性。但是應用到實際開發中的話

TensorFlowtf.nn.conv2d是怎樣實現卷積的?有1*11×1卷積介紹

除去name引數用以指定該操作的name,與方法有關的一共五個引數: 第一個引數input:指需要做卷積的輸入影象,它要求是一個Tensor,具有[batch, in_height, in_width, in_channels]這樣的shape,具體含義是[訓練時一個batch的圖片數量, 圖片

java動態代理+ThreadLocal實現資料來源及事務管理

一、前言         小demo只是思想的一個簡單實現,距離用在生產環境還有一定距離,只是五一勞動節放假宅在家用來鍛鍊一下思維,不嚴謹的地方還望見諒。想要看更完整的示例程式碼,請檢視mybatis原始碼,pooled類的實現。 二、難點分析         JDBC資

網際網路公司的面試是如何360°無死角考察候選人的?上篇石杉的架構筆記

歡迎關注個人公眾號:石杉的架構筆記(ID:shishan100) 週一至週五早8點半!精品技術文章準時送上! 一、寫在前面 最近收到不少讀者反饋,說自己在應聘一些中大型網際網路公司的Java工程師崗位時遇到了不少困惑。 這些同學說自己其實也做了精心準備,網上搜集了不少Java面試題,然而實際去網際網路公司面

面試吃透了這些Redis知識點,面試一定覺得你很NB乾貨 | 建議珍藏

是資料結構而非型別   很多文章都會說,redis支援5種常用的資料型別,這其實是存在很大的歧義。redis裡存的都

MySQL我這樣分析MySQL中的事務面試對我刮目相看!!

## 寫在前面 > 相信大部分小夥伴在面試過程中,只會針對面試官提出的表面問題來進行回答。其實不然,面試官問的每一個問題都是經過深思熟慮的,面試的時間相對來說也是短暫的,面試官不可能在很短的時間內就對你非常瞭解,他想通過幾個問題來考察你所掌握的知識的深度和廣度,如果你只是回答面試官表面問你的問題,向擠

面試百度面試

使用 自我介紹 端口 inux 簡單的 vector 系統工程 lis 工程 核心系統工程師,應該是涼了,雖然是電話面試可我還是緊張了·····而且我學的太淺了。 ———————————————————————————————————————— 上來先讓我簡單的自我介紹,我

React 常用面試題目與分析

作者:王下邀月熊 連結:https://zhuanlan.zhihu.com/p/24856035 來源:知乎 著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。 呼叫 setState 之後發生了什麼? 在程式碼中呼叫setState函式之後,React 會將傳入的引數物件與元件當前的狀態

面試第一次面試總結

         9月10號,早,起床和其他6位同學打的去火車站趕早上去武漢的動車。大約10點30抵達武昌火車站。出火車站後就搭公交車去往中南民族大學。          在附近找到旅館安頓了下來。下午就過去中南民族大學熟悉下筆試面試的位置。我們去應聘的公司是上海德邦物流。晚上開始筆試,時間為一個小時。感覺

演算法資料結構面試演算法題目

1 陣列去重 python實現 #呼叫內建函式去重 def func(str): len1=len(str) len2=len(list(set(str))) print("去重後的結果是:",list(set(str)),"\t去重個數是:",(len1-len2)) #for 迴圈

筆試面試運維面試問答

1. 如何判斷 MySQL 主從是否同步?該如何使其同步? Slave_IO_Running Slave_SQL_Running; 略 2. MySQL 的 innodb 如何定位鎖問題,MySQL 如何減少主從複製延遲? mysql的innodb如何定位鎖問題

搬運總結一下面試中被問到的jdk幾個版本之間的區別問題

1.5 1.自動裝箱與拆箱: 2.列舉(常用來設計單例模式) 3.靜態匯入 4.可變引數 5.內省 1.6 1.Web服務元資料 2.指令碼語言支援 3.JTable的排序和過濾 4.更簡單,更強大的JAX-WS 5.輕量級Http Server 6.嵌入式資料庫 Derby

面試26.英語面試

  如果你是一個具有戰略眼光,期待進入國際性跨國大企業的求職者,本章值得你仔細研讀。   英語面試主要考查兩個部分:英語口語能力和你做人的特質。外企會有專門的人力資源經理和你聊天,會問你關於人生、經歷、團隊合作、成功收穫、失敗教訓等一系列問題。這裡和一般的技術類面試不同,不是