概述
事務必須具有原子性、一致性、隔離性和持久性。雖然首字母縮寫詞容易記憶,但是每個詞的含義不是很明顯。以下是簡要說明。
● 原子性(Atomicity):原子性可確保要麼執行所有更新,要麼什麼也不發生。由於事務中的原子性保障,開發人員不必編寫代碼來處理更新成功而另一個沒有成功的情況。
● 一致性(Consistency):一致性意味著事務的結果使得系統保持一致狀態。在事務啟動之前,數據保持有效的狀態,這與事務結束時一樣。一致性還確保了事務必須使得數據庫保持一致狀態,如果事務的部分操作失敗,則其他部分也必須回到原來的狀態。
● 隔離性(Isolation):多個用戶可能同時訪問同一個數據庫。使用隔離性能夠保證在事務完成之前,該事務外部不能看到事務中的數據改變。也不能訪問一些中間狀態,如果事務終止這些狀態將不會發生。
● 持久性(Durability):持久性意味著即使是系統崩潰也能夠保證一致性狀態。如果數據庫系統崩潰,則持久性必須保證已經提交的事務確實寫入了數據庫。
事務類型
事務分為本地事務和分布式事務兩種類型。
● 本地事務:該類型事務使用已知數據源(例如SQL Server),同時還是單階段事務。若單個數據庫中保存了所有有關事務的數據,對自身可以強制使用ACID規則。這意味著在單個數據庫服務器中(例如SQL Server),只要使用同一個連接,則可以跨數據庫使用本地事務。
● 分布式事務:該類型事務使用多個已知事務數據源。分布式行為可能需要從消息隊列服務器中讀取消息,從SQL Server數據庫中獲取數據,以及將消息寫入其他數據庫。
一些軟件包(例如MSDTC)能夠以編程方式輔助實現分布式事務,通過使用一些方法(例如兩階段提交和回滾)能夠控制跨越所有數據源的提交和回滾行為,以便保證集成性。MSDTC僅可用於兼容事務管理接口的應用程序。當前可用的應用程序有MSMQ、SQL Server、Oracle、Sybase和其他當前可用的應用程序(稱為資源管理器)。
兩階段提交
在分布式事務環境中,不同的資源管理器需要實現可靠的提交協議,最為常見的實現是兩階段提交。在兩階段提交中,實際的提交工作分為兩個階段:
● 第一個階段包括為提交准備一些所需的更改。這樣,RM(資源管理器)就會與事務協調器通信,告知其更新准備已經就緒,准備執行提交,但實際還不進行提交。
● 一旦所有資源管理器都告知事務協調器准備工作就緒,那麼事務協調器將使所有參與者都了解繼續工作准備好,接著執行更改。
在兩階段提交中,單個或者多個數據庫能夠參與分布式事務。實際上,任何在MSDTC事務中登記的對象都能夠參與由MSDTC管理的分布式事務。例如,MSMQ能夠參與由兩個SqlConnection對象連接兩個不同數據庫的事務。簡單描述兩階段提交顯然過於簡單化,而深入講解兩階段提交又超出了本書范圍。既然讀者對事務有了初步認識,就能夠理解.NET 1.x提供的針對事務過程的支持。
四種事務處理
一、SQL事務
sql事務是使用SQL server自身的事務:在存儲過程中直接使用Begin Tran,Rollback Tran,Commit Tran實現事務:
優點:執行效率最佳
限制:事務上下文僅在數據庫中調用,難以實現復雜的業務邏輯。
示例:( SQL Server自帶的AdventureWorks數據為例)
帶事務的儲存過程:
CREATE PROCEDURE dbo.spModifyAddress
(
@City nvarchar(30),
@AddressID int,
@PostalCode nvarchar(15),
@Name nvarchar(50),
)
AS
begin Tran
Update Address Set City=@City,PostalCode=@PostalCode where AddressID=@AddressID
update AddressType set Name = @Name where AddressTypeID = @AddressID
declare @UpdateError int
select @UpdateError=@@error
if(@UpdateError=0)
COMMIT Tran
else
ROLLBACK Tran
GO
調用:
public void SQLTran()
{
SqlConnection conn = new SqlConnection("Data Source=127.0.0.1;Initial Catalog=AdventureWorks;Persist Security Info=True;User ID=sa;Password=123;");
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "spModifyAddress";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection = conn;
conn.Open();
SqlParameter[] paras = new SqlParameter[]{
new SqlParameter ("@AddressID",SqlDbType.Int,4),
new SqlParameter ("@City",SqlDbType.NVarChar,30),
new SqlParameter ("@PostalCode",SqlDbType.NVarChar,32),
new SqlParameter ("@Name",SqlDbType.NVarChar ,50)};
paras[0].Value = "2";
paras[1].Value = "zhejang";
paras[2].Value = "315000";
paras[3].Value = "group";
foreach (SqlParameter para in paras)
{
cmd.Parameters.Add(para);
}
cmd.ExecuteNonQuery();
}
二、ADO.net事務
Ado.net事務可能是大家一般都用的
優點:簡單,效率和數據庫事務差不多。
缺點:事務不能跨數據庫,只能在一個數據庫連接上。如果是兩個數據庫上就不能使用該事務了。
示例:
public void SQLTran()
{
SqlConnection conn = new SqlConnection("Data Source=127.0.0.1;Initial Catalog=AdventureWorks;Persist Security Info=True;User ID=sa;Password=123;");
SqlTransaction sqlTran = conn.BeginTransaction();
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "spModifyAddress";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection = conn;
conn.Open();
cmd.Transaction = sqlTran;
AddParameter(cmd);
try
&n