Sql Server數據庫事務介紹Sql語句,SqlTransaction和TransactionScope的使用方法

  1. 數據庫事務是什麼?

事務是作爲單個邏輯工作單元執行的一系列操作。一個邏輯工作單元必須有四個屬性,稱爲原子性、一致性、隔離性和持久性 (ACID) 屬性,只有這樣才能成爲一個事務。

原子性

事務必須是原子工作單元;對於其數據修改,要麼全都執行,要麼全都不執行。

一致性

事務在完成時,必須使所有的數據都保持一致狀態。在相關數據庫中,所有規則都必須應用於事務的修改,以保持所有數據的完整性。事務結束時,所有的內部數據結構(如 B 樹索引或雙向鏈表)都必須是正確的。

隔離

由併發事務所做的修改必須與任何其他併發事務所做的修改隔離。事務識別數據時數據所處的狀態,要麼是另一併發事務修改它之前的狀態,要麼是第二個事務修改它之後的狀態,事務不會識別中間狀態的數據。這稱爲可串行性,因爲它能夠重新裝載起始數據,並且重播一系列事務,以使數據結束時的狀態與原始事務執行的狀態相同。

持久性

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

Sql語句事務

Sql Server2005/2008提供了begin trancommit tranrollback tran三個語句來顯示的使用事務。begin tran表示事務開始,commit tran表示事務提交,rollback tran表示事務回滾。具體代碼如下:

代碼
1 begin try
2 begin tran
3 insert into dbo.TransTestTable values (66,'66');
4 update dbo.TransTestTable set [Name] = '77' where [Id] = 66;
5 --RAISERROR ('Error raised in TRY block.',16,1);
6 commit tran
7 end try
8 begin catch
9 rollback tran
10 end catch
11  

 

 代碼中的begintry和begin catch是捕獲異常時使用的,只在sqlserver2005/2008中支持,sql server 2000上不支持這個語句。在begin try 和 end try之間的代碼運行時如果發生異常,則程序會跳轉到begin catch和end catch中執行相關的rollback tran回滾操作。在begin tran和commit tran之間就是一個事務,insert和update必須同時成功,否則就同時失敗。RAISERROR 語句的意思是拋出一個異常,只在sql server2005/2008中支持,sql server 2000上不支持這個語句。

      執行上面的代碼,我們會發現,插入和更新同時都成功了。把RAISERROR的註釋去掉後,再執行,我們會發現,插入和更新都回滾了。因爲RAISERROR拋出異常後,沒有執行到commit tran,而是直接執行begin catch裏面的rollback tran回滾語句了

SqlTransaction使用:

SqlTransactionSystem.Data.SqlClient命名空間下的一個事務類,主要方法有Commit()Rollback()兩個函數,更多方法和屬性請參考MSDN。具體代碼如下:

代碼
1 static void Main(string[] args)
2 {
3
4 SqlConnection sqlConn = new SqlConnection(
5 ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString);
6 SqlTransaction sqlTrans = null;
7 try
8 {
9 sqlConn.Open();
10 sqlTrans = sqlConn.BeginTransaction();//事務開始
11   SqlCommand sqlComm = new SqlCommand("", sqlConn, sqlTrans);
12 sqlComm.CommandTimeout = 120;
13 sqlComm.CommandType = System.Data.CommandType.Text;
14 string insertSql = "insert into dbo.TransTestTable values (66,'66');";
15 string updateSql = "update dbo.TransTestTable set [Name] = '77' where [Id] = 66;";
16 sqlComm.CommandText = insertSql;
17 sqlComm.ExecuteNonQuery();//執行insert
18   sqlComm.CommandText = updateSql;
19 sqlComm.ExecuteNonQuery();//執行update
20 //throw new Exception("test exception.the transaction must rollback");
21  
22 sqlTrans.Commit();//事務提交
23   }
24 catch (Exception ex)
25 {
26 sqlTrans.Rollback();//事務回滾
27   Console.WriteLine(ex.Message);
28 }
29 finally
30 {
31 if (sqlConn.State != System.Data.ConnectionState.Closed)
32 sqlConn.Close();
33 }
34
35 Console.ReadLine();
36 }
37

 

上面的代碼顯示了SqlTransaction類的基本使用方法。首先使用SqlConnection建立連接後,sqlConn.BeginTransaction()表示事務的開始,在執行一些基本操作後(代碼是執行一個insert和一個update)後,執行sqlTrans.Commit();表示事務提交,這時候,剛纔insertupdate的數據在數據庫才能被使用。如果把throw new Exception("test exception.the transaction mustrollback");這句的註釋去掉,我們會發現,程序沒有執行提交,而是直接執行了catch中的Rollback(),進行了回滾。那麼剛纔的insertupdate一起被回滾。

TransactionScope用法:

TransactionScope繼承IDisposable接口,所以一般在using中使用。具體代碼如下:

代碼
1 static void Main(string[] args)
2 {
3 using (TransactionScope scope = new TransactionScope())
4 {
5 SqlConnection sqlConn = new SqlConnection(
6 ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString);
7 sqlConn.Open();
8
9 string insertSql = "insert into [TransTestTable] values(11,'11')";
10 string updateSql = "update [TransTestTable] set [Name] = '111' where [Id] = 11";
11
12 SqlCommand sqlComm = new SqlCommand(insertSql, sqlConn);
13 sqlComm.CommandType = System.Data.CommandType.Text;
14 sqlComm.ExecuteNonQuery();
15
16 sqlComm = new SqlCommand(updateSql, sqlConn);
17 sqlComm.CommandType = System.Data.CommandType.Text;
18 sqlComm.ExecuteNonQuery();
19
20 sqlConn.Close();
21
22 scope.Complete();
23 }
24
25 Console.ReadLine();
26 }
27

 

using中定義了一個TransactionScope,相當於定義了一個事務範圍即這個事務作用域爲using內。程序執行了兩個動作,一個insert,一個update,最後執行了scope.Complete();相當於提交事務。如果把scope.Complete();註釋掉,我們會發現insertupdate都被回滾了,因爲在using作用域內,如果沒有提交命令,那麼scope在銷燬時,會自動回滾所有的操作。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章