.NET三种事务处理详解
體系結構:SQL事務處理、ADO.NET事務處理、COM+事務處理
?
數據庫事務處理:T-SQL語句中完成, Begin Transaction Commit/Roll Back
BEGIN TRANSACTION:
BEGIN TRANSACTION { tran_name} {trans_name1| @tran_name-veriable1}事務名不得超過32個字符,否則自截斷。此處變量的類型僅可以是char、varchar、nchar、nvarchar WITH MARK ['DESCRIPTION'] 指定在日志中標記事務 EXPRESSION2 |
BEGIN TRANS啟動一個本地事務,但是在應用程序執行一個必須的記錄操作之前,他不被記錄在事務日志中。
With Mark選項使得事務名被置于事務日志中,將數據還原到早期狀態時,可使用標記事務代替日期和時間。
在未標記的數據庫事務中可以嵌套標記的事務。如
BEGIN TRAN T1 UPDATE table1 ... BEGIN TRAN M2 WITH MARK UPDATE table2 ... SELECT * from table1 COMMIT TRAN M2 UPDATE table3 ... COMMIT TRAN T1 |
命名事務示例:
DECLARE @TranName VARCHAR(20) SELECT @TranName = 'MyTransaction' BEGIN TRANSACTION @TranName USE AdventureWorks DELETE FROM AdventureWorks.HumanResources.JobCandidate WHERE JobCandidateID = 13 COMMIT TRANSACTION @TranName |
標記事務示例:
BEGIN TRANSACTION CandidateDelete WITH MARK N'Deleting a Job Candidate' USE AdventureWorks DELETE FROM AdventureWorks.HumanResources.JobCandidate WHERE JobCandidateID = 13 COMMIT TRANSACTION CandidateDelete |
COMMIT TRANSACTION:
COMMIT {TRAN|TRANSACTION} [transaction_name | [@tran_name_variable ] ]同BEGIN部分的規則 [ ; ] |
提交一般事務示例:
USE AdventureWorks BEGIN TRANSACTION DELETE FROM HumanResources.JobCandidate WHERE JobCandidateID = 13 COMMIT TRANSACTION |
提交嵌套事務示例:
BEGIN TRANSACTION OuterTran ????INSERT INTO TestTran VALUES (1, 'aaa') ????BEGIN TRANSACTION Inner1 ????????INSERT INTO TestTran VALUES (2, 'bbb') ????????BEGIN TRANSACTION Inner2 ????????????INSERT INTO TestTran VALUES (3, 'ccc') ????????COMMIT TRANSACTION Inner2 ????COMMIT TRANSACTION Inner1 COMMIT TRANSACTION OuterTran |
ROLLBACK TRANSACTION
ROLLBACK { TRAN | TRANSACTION } --transaction_name同上,此處savepoint_name規則同transaction_name,為SAVE TRANSACTION 語句中的savepoint_name,用于條件回滾之影響事務的一部分 [ transaction_name | @tran_name_variable | savepoint_name | @savepoint_variable ] [ ; ] |
示例:
USE TempDB CREATE TABLE ValueTable ([value] int) BEGIN TRAN Transaction1 INSERT INTO ValueTable VALUES(1) INSERT INTO ValueTable VALUES(2) SELECT * FROM ValueTable ROLLBACK TRAN Transaction1 SELECT * FROM ValueTable INSERT INTO ValueTable VALUES(3) INSERT INTO ValueTable VALUES(4) SELECT * FROM ValueTable DROP TABLE ValueTable |
結果:
綜合示例:
begin TRAN ????declare @orderDetailsError int,@procuntError int delete from [order details] where productid=42 select @orderDetailsError =@@error delete from products where productid=42 select @procuntError=@@error if(@orderDetailsError =0 and @procuntError=0) ????COMMIT TRAN else ????ROLLBACK TRAN |
ADO.NET事務處理:
示例:
public void ExecuteNoneSql(string p_sqlstr, params string[] p_cmdStr) { using (SqlConnection conn = new SqlConnection(p_sqlstr)) { Conn.Open(); SqlCommand cmd = new SqlCommand(); cmd.Connection = conn; SqlTransaction trans = null; trans = conn.BeginTransaction(); //初始化事務 cmd.Transaction = trans; //綁定事務 try { for (int i = 0; i < p_cmdStr.Length; i++) { cmd.CommandText = p_cmdStr[i]; cmd.CommandType = CommandType.Text; cmd.ExecuteNonQuery(); } trans.Commit(); //提交 } catch (SqlException e) { if (trans != null) trans.Rollback(); //回滾 else {//寫日志} } } } |
帶保存點回滾示例:
using (SqlConnection conn = new SqlConnection(p_sqlstr)) { conn.Open(); SqlCommand cmd = new SqlCommand(); cmd.Connection = conn; SqlTransaction trans = conn.BeginTransaction("table"); cmd.Transaction = trans; try { cmd.CommandText = "Insert into table_name1 values(values1,values2,....)"; cmd.CommandType = CommandType.Text; cmd.ExecuteNonQuery(); cmd.CommandText = "Insert into table_name2 values(values1,values2,....)"; cmd.CommandType = CommandType.Text; cmd.ExecuteNonQuery(); trans.Save("table1"); cmd.CommandText = "Insert into table_name2 values(values1,values2,....)"; cmd.CommandType = CommandType.Text; cmd.ExecuteNonQuery(); trans.Save("table2"); trans.Commit(); } catch { try { trans.Rollback("table2") ; } catch { try{ trans.Rollback("table1") ; } catch{ trans.Rollback("table") ; } } } } |
COM+事務處理:
COM+事務必須繼承自System.EnterpriseServices.ServicedComponent。其實WEB也是繼承自該類,所以WEB支持COM+事務處理。
第一步、新建一個COM+事務處理的類。
[Transaction(TransactionOption.Required)] public class MyCOMPlus : System.EnterpriseServices.ServicedComponent { .............. } |
TransactionOption為枚舉類型,具有五個選項。
DISABLED忽略當前上下文中的任何事務
NOTSUPPORTED使用非受控事件創建組件
REQUIRED如有事務存在則共享事務,如有必要則創建事務(事務池,事務處理中所選擇項)REQUIRESNEW是有新建的事務,與上下文無關
SUPPORTED如果事務存在則共享事務。
一般來說COM+中的組件需要REQUIRED或SUPPORTED。當組件需要同活動中其他事務處理的提交或回滾隔離開來的時候建議使用REQUIRESNEW。COM+事務有手動處理和自動處理,自動處理就是在所需要自動處理的方法前加上[AutoComplete],根據方法的正常或拋出異常決定提交或回滾。手動處理其實就是調用EnableCommit()、SetComplete()、SetAbort()方法。
手動處理示例:
public void TestTransaction() { try { ContextUtil.EnableCommit(); //對應BEGIN TRANSACTION InsertRecord(); DeleteRecord(); UpdateRecord2(); ContextUtil.SetComplete(); //對應TRANSACTION.COMMIT } catch (Exception ex) { ContextUtil.SetAbort(); //對應TRANSACTION.ROLLBACK } } |
自動事務處理示例(只需要在方法前面加上AutoComplete的attribute聲明即可):
[AutoComplete] public void TestTransaction() { InsertRecord(); DeleteRecord(); UpdateRecord2(); } |
?
三者性能比較:
性能排名: SQL事務處理>ADO.NET事務處理>COM+事務處理
SQL事務處理只需要進行一次數據庫交互,優點就是速度很快,而且所有邏輯包含在一個單獨的調用中,與應用程序獨立,缺點就是與數據庫綁定。
ADO.NET需要2n次數據庫往返,但相對而言,ADO.NET事務處理性能比SQL事務處理低很少,在一般應用程序中可以忽略。而且ADO.NET事務處理將事務處理與數據庫獨立,增加了程序的移植性。而且他也可以橫跨多個數據庫,不過他對于數據庫的類型要求一致。
COM+事務處理性能最低,主要因為COM+本身的一些組件需要內存開銷。但COM+可以橫跨各種數據存儲文件,這一點功能是前兩者所無法媲美的。
轉載于:https://www.cnblogs.com/BLoodMaster/archive/2010/03/18/1688660.html
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的.NET三种事务处理详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 时光一去不复返
- 下一篇: PHP Memcached + APC