脫離 Spring 實現複雜嵌套事務,之四(NESTED - 嵌套事務)

    本文是<實現 Spring 的事務控制>系列文章中一篇。本文假設讀者已經閱讀並理解《實現 Spring 的事務控制,之一(必要的概念)》文中所涉及的概念(當前鏈接引用計數),以及數據庫鏈接的(new狀態數據庫

PROPAGATION_NESTED(嵌套事務)

定義:

    在當前事務上開啓一個子事務(Savepoint),若是遞交主事務。那麼連同子事務一同遞交。若是遞交子事務則保存點以前的全部事務都會被遞交。 學習

解釋:

    所謂嵌套事務,指的就是 NESTED 行爲。這一點你們要格外注意。 spa

    這是因爲「嵌套事務」這個詞在 Spring 以後具有了多重含義。一種是指 Spring 提供的事務控制體系中那種基於多行爲的嵌套事務控制策略。另一種就是原汁原味 JDBC 提供給咱們的嵌套事務。本文所提到的嵌套事務在沒有特殊說明的狀況下都是指後者。 .net

    好了迴歸正題,何爲嵌套事務? blog

    先不看定義,咱們從字面理解,所謂嵌套,是指一層套着另外一層的意思。那麼真實狀況是不是這樣的呢?先看一下下面這張表: 接口

時間 事務1 事務2
T1 開始主事務
T2 操做1...
T3
建立事務保存點
T4 操做2...
T5
遞交保存點
T6 操做3...
T7 回滾主事務

    上面這張表中列出了咱們理想的事務遞交方式。咱們認爲事務2遞交不會影響到事務1。可是實際狀況是錯誤的。 事務

    咱們知道事務保存點的功能有點至關於「錨標記」它的功效是在一個長長的事務中經過保存點來分割不一樣的階段。因爲在標記「錨」時候是有前後順序的,所以事務的不一樣階段也是有順序的,這個是你們都能理解的邏輯。 ci

    另外咱們在學習數據庫方面知識時候,知道在設置一個事務保存點以前一般會經過「begin tran....」開啓事務,而後會經過「savepoint xxx」語句聲明保存點。最後遞交事務的時候經過「commit」語句遞交。若是僅此而已則數據庫事務會總體遞交,遞交的內容包含了自 commit 開始往前一直到最近的一個 commit 或者 begin tran 之間的全部內容。而commit 語句能夠跟隨一個參數「commit xxx」。那個參數就是再遞交以前曾經設置的保存點名稱。 get

    在數據庫中遞交一個保存點的含義是指遞交操做只涉及到這個保存點以前的操做。假若我前後設置了兩個保存點,而後我遞交最後建立的那個保存點。那麼第一個保存點以前的操做很顯然也進入了數據庫。由於這是保存點自己的工做性質。 it

    咱們在回到前面表格中提到的例子,當在 T5 階段遞交保存點的時候,T2 那裏的操做很顯然被正式保存到了數據庫中。即便咱們在 T7 位置執行了回滾操做。可是依然只能影響到 T6。

    爲此你們要各位注意,嵌套事務的真實特性。下面咱們看一看 NESTED 行爲的定義是怎麼說的。

    「在當前事務上開啓一個子事務(Savepoint)」第一句就告訴咱們,事務控制使用的是保存點,因此咱們腦殼裏應該有了一個先前印象。接下來「若是遞交主事務,那麼連同子事務一同遞交」這也知足了咱們前面提到的「commit」無參數那個狀況的描述。最後「若是遞交子事務則一部分主事務也會跟隨遞交。」這句話偏偏就是再說咱們上面剛剛提到的內容。

具備 Savepoint 特徵的事務

    呵呵,至此爲止咱們已經接觸到了「引用計數」、「Suspent」、「new狀態」三個狀態。今天再向你們介紹一種狀態叫「Savepoint」至此咱們已經接觸到了實現復瑣事務控制中全部關鍵的狀態。

    我發誓,後面還有一些狀態會介紹給你們,可是請相信我。除了上面這四個狀態比較複雜以外,其它的狀態都很簡單了。不信的話你們能夠繼續關注本文。

    當事務管理器建立事務狀態時,當前鏈接須要建立一個Savepoint給事務狀態。這時候事務狀態就具有了「Savepoint特徵」。

    與具備「new特徵」同樣,「Savepoint特徵」也會協助事務管理器處理 commit & rollback 操做。

工做原理

啓動事務

    與前幾個行爲同樣 NESTED 行爲在啓動事務的時候會判斷當前鏈接是否存在事務。若是存在事務則安插錨點,並設置「Savepoint特徵」。若是不存在事務就啓動事務(咱們知道此時當前鏈接正好知足「new特徵」)。

    因而可知,「new特徵」和「Savepoint特徵」是一個彼此排斥的狀況。這在後面實現的時候會大大減小不少工做。

事務中的數據庫操做

    此時此刻,能夠直接使用 Connection 接口暢快的使用數據庫操做。因爲每次進行數據庫操做都要反覆的申請和釋放數據庫鏈接。這會反覆的使引用計數 +1,-1。 ------「這一過程當中使用的數據庫鏈接都是新的鏈接」。

遞交/回滾事務

    在啓動事務階段提到過,「Savepoint特徵」和「new特徵」是互斥的,所以在執行遞交回滾的時候。須要先判斷是否具備「Savepoint特徵」,若是有就釋放保存點這樣就知足了嵌套事務的要求。 不然就繼續判斷「new」特徵。

相關文章
相關標籤/搜索