1. 程式人生 > 實用技巧 >脫離 Spring 實現複雜巢狀事務,之六(NOT_SUPPORTED - 非事務方式)

脫離 Spring 實現複雜巢狀事務,之六(NOT_SUPPORTED - 非事務方式)

>>> hot3.png

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

PROPAGATION_NOT_SUPPORTED(非事務方式)

定義:

是指如果存在事務則將這個事務掛起,並使用新的資料庫連線。新的資料庫連線不使用事務。

解釋:

NOT_SUPPORTED行為是 Spring 為我們帶來的一種特殊的事務控制行為。在這種行為下它保證了當前對資料庫的操作是相當於 autoCommit 值為 true 。

我們回顧第一篇文章中提到的銀行轉賬業務:“A賬戶可以轉賬給B賬戶,銀行要求能看到當前實時的正在交易的筆數”。我們曾在《REQUIRES_NEW - 獨立事務》一文中見到過如何實現這個需求。現在我在像大家介紹如何通過使用NOT_SUPPORTED 行為實現同樣的業務。

時間 事務1(開啟事務) 事務2(非事務)
T1 開始事務
T2
掛起事務
T3
記錄日誌...
T4
恢復事務
T5 轉賬500元
T6
掛起事
T7
記錄日誌
T8
恢復事務
T9 遞交事務

我們先看事務1,在事務1中展示的是一個完整的轉賬業務功能。它被一個事務所環抱,這個事務保證了轉賬業務的正確執行。

下面我們看一看事務2中是如何處理日誌記錄的。

首先事務2在記錄日誌之前掛起了當前事務,還記得前面在REQUIRES_NEW - 獨立事務》一文中提到的“掛起”操作和“Suspent特徵”麼?

事務2在NOT_SUPPORTED行為下,會掛起當前事務。與REQUIRES_NEW 行為不同的是,它在掛起之後不會在嘗試開啟新的事務。也就是這一點的區別決定了NOT_SUPPORTED 行為與REQUIRES_NEW 行為。

工作原理


開啟事務

事務管理器在建立NOT_SUPPORTED行為事務時,會取得當前連線這一過程會持有當前連線(引用計數+1)。注意:此時持有的資料庫連線並不一定是最終在操作階段使用的資料庫連線

然後通過判斷當前連線是否存在事務狀態,來決定是否通過 執行掛起事務操作。一旦執行了掛起事務的操作就相當於清空了當前的資料庫連線。所以接下來需要重新申請一個數據庫連線,新申請的資料庫連線事務管理器也會持有它(引用計數+1)。

不同於REQUIRES_NEW 行為的是,NOT_SUPPORTED行為下事務管理器是不會開啟新連線的事務的。也就是說當前連線是不會被標記“new”狀態。它一直工作在非事務模式下。

事務中的資料庫操作

無論在開啟事務的時候Connection 此時此刻,可以直接使用 Connection 介面暢快的使用資料庫操作。由於每次進行資料庫操作都要反覆的申請和釋放資料庫連線。這會反覆的使引用計數 +1,-1。

遞交/回滾事務

最後由於不需要管理當前連線的事務,NOT_SUPPORTED 行為需要做的只有草率的處理掉當前連線。然後恢復上一個事務就可以了。


轉載於:https://my.oschina.net/ta8210/blog/200416