關於.NET編程中各種事務的實現
從數據庫事務開始
在很早的以前,我們要實現一個事務通常是基於SQL的數據庫事務,一般的通過SQL查詢語言來實現,如下所示,同時更新兩本書的價格:
BEGIN TRANSACTION UPDATE tb_Book SET Price=122 WHERE IDENT_CURRENT=1001 UPDATE tb_Book SET Price=88 WHERE IDENT_CURRENT=1002 IF @@ERROR <> 0 BEGIN ROLLBACK TRANSACTION END ELSE COMMIT TRANSACTION
ADO.NET事務和分布式事務
隨著.NET技術的不斷發展,可通過ADO.NET來實現,這樣我們可以將事務更好的應用在業務邏輯中,而非數據庫存儲中,這樣能夠更好的實現業務和存儲分離,使的事務被業務邏輯所控制,數據庫專註於數據存儲,達到各負其責的作用,在ADO.NET中事務的寫法是:
using (DbTransaction transaction = connection.BeginTransaction()) { command.Transaction = transaction; try { command.ExecuteNonQuery(); transaction.Commit(); } catch (Exception e) { transaction.Rollback(); throw; } }
上面的代碼只能基於同一個數據庫連接進行,後來為了實現遠程多個數據庫的事務,提出了分布式事務,誇數據庫服務器進行事務關聯:
using (TransactionScope transactionScope = new TransactionScope()) { //操作數據庫服務器1中的數據庫 using (SqlConnection connection = new SqlConnection(connectionString1)) { SqlCommand command = new SqlCommand(commandText1, connection); connection.Open(); command.ExecuteNonQuery(); connection.Close(); } //操作數據庫服務器2中的數據庫 using (SqlConnection connection = new SqlConnection(connectionString2)) { SqlCommand command = new SqlCommand(commandText2, connection); connection.Open(); command.ExecuteNonQuery(); connection.Close(); } transactionScope.Complete(); }
基於文件系統的事務(TXF)
有時候,我們需要將NTFS文件系統的操作進行事務管理,例如:首先將圖片保存到硬盤,然後將文件路徑存入數據庫,這兩個步驟是滿足事務(ACID)原則的,數據庫應該與文件系統保持同步,要麽都刪除,要麽都存在,同生共死。但可惜微軟沒有在.NET中提供這樣的API接口供開發人員使用,零度博主抱著對技術精益求精的態度進行了一番的折騰,終於在國外的一個社區找到了針對操作系統內核(kernel32.dll)封裝的KTM事務管理方案,零度博主針對自己的需求進行了改進,本方案的C#.NET調用方式如下:
using (TransactionScope transactionScope = new TransactionScope()) { string commandText = "UPDATE Book SET Price=88.50 WHERE ID=1001"; var fileStream = TransactedFile.Open(@"log.txt", FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write); StreamWriter streamWrite = new StreamWriter(fileStream); streamWrite.WriteLine(string.Concat(DateTime.Now, commandText)); streamWrite.Flush(); streamWrite.Close(); SqlConnection connection = new SqlConnection(connectionString); SqlCommand command = new SqlCommand(commandText, connection); connection.Open(); command.ExecuteNonQuery(); connection.Close(); transactionScope.Complete(); }
以上示例代碼首先創建TransactionScope事務環境,將文件操作和數據庫操作關聯成成同一個事務,TransactedFile正是上文提到的基於KTM的本地事務封裝,數據庫事務本身支持隱式自動關聯,當前者和後者同時被關聯到TransactionScope事務上下文環境後,就形成了一個完成的事務。上面的示例首先向磁盤的log.txt中寫入當前的時間和要執行的SQL語句,然後通過SQL更新Book價格,如果更新價格失敗則回滾寫入的日誌(自動刪除日誌)。
總之:事務是一個復雜的系統,主要有KTM、DTC和LTM事務,內部實現及其復雜,本文主要簡單說明事務的基本用法,針對原理性的研究請關註零度博客未來的文章,感謝您的閱讀,希望對您有所幫助!
關於.NET編程中各種事務的實現