本文是<實現 Spring 的事務控制>系列文章中一篇。本文假設讀者已經閱讀並理解《實現 Spring 的事務控制,之一(必要的概念)》文中所涉及的概念(當前鏈接、引用計數),以及數據庫鏈接的(new狀態) 數據庫
是指若是存在事務則將這個事務掛起,並使用新的數據庫鏈接。新的數據庫鏈接不使用事務。 spa
NOT_SUPPORTED 行爲是 Spring 爲咱們帶來的一種特殊的事務控制行爲。在這種行爲下它保證了當前對數據庫的操做是至關於 autoCommit 值爲 true 。 .net
咱們回顧第一篇文章中提到的銀行轉帳業務:「A帳戶能夠轉帳給B帳戶,銀行要求能看到當前實時的正在交易的筆數」。咱們曾在《REQUIRES_NEW - 獨立事務》一文中見到過如何實現這個需求。如今我在像你們介紹如何經過使用 NOT_SUPPORTED 行爲實現一樣的業務。 日誌
時間 | 事務1(開啓事務) | 事務2(非事務) |
T1 | 開始事務 | |
T2 | |
掛起事務 |
T3 | |
記錄日誌... |
T4 | |
恢復事務 |
T5 | 轉帳500元 | |
T6 | |
掛起事務 |
T7 | |
記錄日誌 |
T8 | |
恢復事務 |
T9 | 遞交事務 | |
咱們先看事務1,在事務1中展現的是一個完整的轉帳業務功能。它被一個事務所環抱,這個事務保證了轉帳業務的正確執行。 blog
下面咱們看一看事務2中是如何處理日誌記錄的。 接口
首先事務2在記錄日誌以前掛起了當前事務,還記得前面在《REQUIRES_NEW - 獨立事務》一文中提到的「掛起」操做和「Suspent特徵」麼? 事務
事務2在 NOT_SUPPORTED 行爲下,會掛起當前事務。與 REQUIRES_NEW 行爲不一樣的是,它在掛起以後不會在嘗試開啓新的事務。也就是這一點的區別決定了 NOT_SUPPORTED 行爲與 REQUIRES_NEW 行爲。 ci
事務管理器在建立 NOT_SUPPORTED 行爲事務時,會取得當前鏈接這一過程會持有當前鏈接(引用計數+1)。注意:此時持有的數據庫鏈接並不必定是最終在操做階段使用的數據庫鏈接。 get
而後經過判斷當前鏈接是否存在事務狀態,來決定是否經過 執行掛起事務操做。一旦執行了掛起事務的操做就至關於清空了當前的數據庫鏈接。因此接下來須要從新申請一個數據庫鏈接,新申請的數據庫鏈接事務管理器也會持有它(引用計數+1)。 it
不一樣於 REQUIRES_NEW 行爲的是,在 NOT_SUPPORTED 行爲下事務管理器是不會開啓新鏈接的事務的。也就是說當前鏈接是不會被標記「new」狀態。它一直工做在非事務模式下。
不管在開啓事務的時候Connection 此時此刻,能夠直接使用 Connection 接口暢快的使用數據庫操做。因爲每次進行數據庫操做都要反覆的申請和釋放數據庫鏈接。這會反覆的使引用計數 +1,-1。
最後因爲不須要管理當前鏈接的事務,NOT_SUPPORTED 行爲須要作的只有草率的處理掉當前鏈接。而後恢復上一個事務就能夠了。