在處理SSIS包的數據ETL操做過程當中,咱們常常遇到的一個問題就是一系列步驟在運行的過程當中,若是中間的一個步驟失敗了,那麼咱們就須要清理前面已經運行過的步驟所產生的數據或者結果,這每每是一個很頭疼的過程。那麼在SSIS的Package中是否能夠實現事務機制呢?html
咱們知道基於事務咱們能夠保證在一系列操做下的各個步驟,它們要麼所有成功,要麼所有失敗。這裏將介紹在SSIS的Package中一個比較簡單的實現方法。模塊化
首先,創建一個測試表,這個表裏會有一個自增的主鍵標識,而後分別有一個文本和數字類型的字段。腳本以下:測試
USE [DBTEST] spa
CREATE TABLE [dbo].[TBTest]( 設計
[id] [int] IDENTITY(1,1) NOT NULL, 3d
[Title] [nvarchar](50) NULL, htm
[Amount] [decimal](18, 0) NULL, blog
CONSTRAINT [PK_TBTest] PRIMARY KEY CLUSTERED 事務
( ci
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
在SSIS下新創建一個Package,而後加入以下三個步驟:
首先將數據表中的數據清空,而後INSERT幾條數據,最後嘗試進行一個失敗的更新。
在LOAD DATA步驟中,簡單的手動插入幾條數據。
數據源語句的查詢。
而後在第三步更新數據的步驟中,咱們嘗試對主鍵進行更新,這裏的目的主要就是要引起一個異常而後讓後續介紹的事務進行回滾。
首先看一下直接運行的結果。
能夠看到在第三步中觸發的異常。
而且在表中能夠看到,數據確實沒有被回滾,還在表中。
接下來,咱們開始嘗試在這個Package中加入事務機制。
如上圖,SSIS的這種模塊化真的是很是好,相信你們一看這個圖就馬上明白接下來要作什麼了。
在BEGINTRAN模塊中的代碼:
BEGIN TRANSACTION;
在COMMITTRAN模塊中的代碼:
COMMIT TRANSACTION;
最後,在ROLL BACK模塊中的代碼:
ROLLBACK TRANSACTION;
而後,運行包。
發如今ROLL BACK模塊中仍是報錯了,錯誤信息以下:
而且,事務沒有回滾。在表中仍是能夠看到被INSERT的數據。
這裏的關鍵在於,每個模塊默認利用SSIS裏的數據源鏈接,都是從新開啓一個新的鏈接,因此這樣在一個新鏈接裏的ROLLBACK沒有前文,確定是要失敗的。
因此,這裏須要關注SSIS包數據源鏈接的一個屬性,就是RetainSameConnection,它默認爲False,把它設置成True,就能夠保證在一個包裏調用的數據源鏈接都是同一個鏈接。
設置好這個屬性以後,咱們再來運行下包。
能夠發現,當數據流在有異常被觸發的時候,ROLL BACK模塊成功的進行了回滾。
從表中發現,數據確實被回滾了。
其實實現數據回滾的方法也不少,這是利用SSIS自帶功能的一個實現,他確實實現起來相對簡單一些。這樣能夠避免包失敗後,從新運行包致使前面的步驟被重複運行。園子裏另一個兄弟BI Work介紹的這篇文章利用Check Point來避免這種狀況的發生。除此以外,也能夠在設計Package的時候,在包的開頭就設計好對可能影響到的數據的清理工做。總之實現的方法不少,在實際項目中徹底能夠根據實際的狀況來決定使用哪個方案。
另外,在SSIS中實際上也能夠利用MSDTC,可是它實現起來多少有必定的門檻,若是你對MSDTC感興趣能夠參考園子裏另一個朋友對它的介紹。