1. 程式人生 > >關於.NET編程中各種事務的實現

關於.NET編程中各種事務的實現

AC 圖片 flush 針對 mod 發展 後來 dll let

從數據庫事務開始

在很早的以前,我們要實現一個事務通常是基於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編程中各種事務的實現