C#資料庫事務原理及實踐

來源:互聯網
上載者:User

什麼是資料庫事務

資料庫事務是指作為單個邏輯工作單元執行的一系列操作。

設想網上購物的一次交易,其付款過程至少包括以下幾步資料庫操作:

· 更新客戶所購商品的庫存資訊

· 儲存客戶付款資訊--可能包括與銀行系統的互動

· 產生訂單並且儲存到資料庫中

· 更新使用者相關資訊,例如購物數量等等

正常的情況下,這些操作將順利進行,最終交易成功,與交易相關的所有資料庫資訊也成功地更新。但是,如果在這一系列過程中任何一個環節出了差錯,例如在更新商品庫存資訊時發生異常、該顧客銀行帳戶存款不足等,都將導致交易失敗。一旦交易失敗,資料庫中所有資訊都必須保持交易前的狀態不變,比如最後一步更新使用者資訊時失敗而導致交易失敗,那麼必須保證這筆失敗的交易不影響資料庫的狀態--庫存資訊沒有被更新、使用者也沒有付款,訂單也沒有產生。否則,資料庫的資訊將會一片混亂而不可預測。

資料庫事務正是用來保證這種情況下交易的平穩性和可預測性的技術。

資料庫事務的ACID屬性

交易處理可以確保除非事務性單元內的所有操作都成功完成,否則不會永久更新面向資料的資源。通過將一組相關操作組合為一個要麼全部成功要麼全部失敗的單元,可以簡化錯誤恢複並使應用程式更加可靠。一個邏輯工作單元要成為事務,必須滿足所謂的ACID(原子性、一致性、隔離性和持久性)屬性:

· 原子性

事務必須是原子工作單元;對於其資料修改,要麼全都執行,要麼全都不執行。通常,與某個事務關聯的操作具有共同的目標,並且是相互依賴的。如果系統只執行這些操作的一個子集,則可能會破壞事務的總體目標。原子性消除了系統處理操作子集的可能性。

· 一致性

事務在完成時,必須使所有的資料都保持一致狀態。在相關資料庫中,所有規則都必須應用於事務的修改,以保持所有資料的完整性。事務結束時,所有的內部資料結構(如 B 樹索引或雙向鏈表)都必須是正確的。某些維護一致性的責任由應用程式開發人員承擔,他們必須確保應用程式已強制所有已知的完整性條件約束。例如,當開發用於轉帳的應用程式時,應避免在轉帳過程中任意移動小數點。

· 隔離性

由並發事務所作的修改必須與任何其它並發事務所作的修改隔離。事務查看資料時資料所處的狀態,要麼是另一併發事務修改它之前的狀態,要麼是另一事務修改它之後的狀態,事務不會查看中間狀態的資料。這稱為可串列性,因為它能夠重新裝載起始資料,並且重播一系列事務,以使資料結束時的狀態與原始事務執行的狀態相同。當事務可序列化時將獲得最高的隔離等級。在此層級上,從一組可並存執行的事務獲得的結果與通過連續運行每個事務所獲得的結果相同。由於高度隔離會限制可並存執行的事務數,所以一些應用程式降低隔離等級以換取更大的輸送量。

· 持久性

事務完成之後,它對於系統的影響是永久性的。該修改即使出現致命的系統故障也將一直保持。

DBMS的責任和我們的任務

企業級的資料庫管理系統(DBMS)都有責任提供一種保證事務的物理完整性的機制。就常用的SQL Server2000系統而言,它具備鎖定裝置隔離事務、記錄裝置保證事務持久性等機制。因此,我們不必關心資料庫事務的物理完整性,而應該關注在什麼情況下使用資料庫事務、事務對效能的影響,如何使用事務等等。

本文將涉及到在.net架構下使用C#語言操縱資料庫事務的各個方面。

體驗SQL語言的事務機制

作為大型的企業級資料庫,SQL Server2000對事務提供了很好的支援。我們可以使用SQL語句來定義、提交以及復原一個事務。

如下所示的SQL代碼定義了一個事務,並且命名為"MyTransaction"(限於篇幅,本文並不討論如何編寫SQL語言程式,請讀者自行參考相關書籍):

DECLARE @TranName VARCHAR(20)
SELECT @TranName = 'MyTransaction'
BEGIN TRANSACTION @TranNameGOUSE pubs
GO
UPDATE roysched
SET royalty = royalty * 1.10
WHERE title_id LIKE 'Pc%'
GO
COMMIT TRANSACTION MyTransaction
GO

這裡用到了SQL Server2000內建的樣本資料庫pubs,提交事務後,將為所有暢銷電腦書籍支付的版稅增加 10%。

開啟SQL Server2000的查詢分析器,選擇pubs資料庫,然後運行這段程式,結果顯而易見。

可是如何在C#程式中運行呢?我們記得在普通的SQL查詢中,一般需要把查詢語句賦值給SalCommand.CommandText屬性,這裡也就像普通的SQL查詢語句一樣,將這些語句賦給SqlCommand.CommandText屬性即可。要注意的一點是,其中的"GO"語句標誌著SQL批處理的結束,編寫SQL指令碼是需要的,但是在這裡是不必要的。我們可以編寫如下的程式來驗證這個想法:

//TranSql.csusing System;
using System.Data;
using System.Data.SqlClient;
namespace Aspcn
{
 public class DbTranSql
 {
  file://將事務放到SQL Server中執行
  public void DoTran()
  {
   file://建立串連並開啟
   SqlConnection myConn=GetConn();myConn.Open();
   SqlCommand myComm=new SqlCommand();
   try
   {
    myComm.Connection=myConn;
    myComm.CommandText="DECLARE @TranName VARCHAR(20) ";
    myComm.CommandText+="SELECT @TranName = 'MyTransaction' ";
    myComm.CommandText+="BEGIN TRANSACTION @TranName ";
    myComm.CommandText+="USE pubs ";
    myComm.CommandText+="UPDATE roysched SET royalty = royalty * 1.10 WHERE title_id LIKE 'Pc%' ";
    myComm.CommandText+="COMMIT TRANSACTION MyTransaction ";
    myComm.ExecuteNonQuery();
   }
   catch(Exception err)
   {
    throw new ApplicationException("事務操作出錯,系統資訊:"+err.Message);
   }
   finally
   {
    myConn.Close();
   }
  }
  file://擷取資料連線
  private SqlConnection GetConn()
  {
   string strSql="Data Source=localhost;Integrated Security=SSPI;user id=sa;password=";
   SqlConnection myConn=new SqlConnection(strSql);
   return myConn;
  }
 }
 public class Test
 {
  public static void Main()
  {
   DbTranSql tranTest=new DbTranSql();
   tranTest.DoTran();
   Console.WriteLine("交易處理已經成功完成。");
   Console.ReadLine();
  }
 }
}

注意到其中的SqlCommand對象myComm,它的CommandText屬性僅僅是前面SQL代碼字串串連起來即可,當然,其中的"GO"語句已經全部去掉了。這個語句就像普通的查詢一樣,程式將SQL文本事實上提交給DBMS去處理了,然後接收返回的結果(如果有結果返回的話)。

很自然,我們最後看到了輸出"交易處理已經成功完成",再用企業管理器查看pubs資料庫的roysched表,所有title_id欄位以"PC"開頭的書籍的royalty欄位的值都增加了0.1倍。

這裡,我們並沒有使用ADO.net的交易處理機制,而是簡單地將執行事務的SQL語句當作普通的查詢來執行,因此,事實上該事務完全沒有用到.net的相關特性。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.