本文摘自:http://www.cnblogs.com/zhangxj-sun/archive/2012/07/13/Tran.html
1.SQL和存儲過程級別的事務
這個也是我經常用到的事務,其實這個可以用一個很簡單的例子來形容就是銀行取錢的問題,兩個不同地方的存摺但是是同一個賬戶,當其中一個地方的存摺發生改變另外一個地方的存摺數據也會跟着發生改變,存儲過程實例:
CREATE PROCEDURE TRAN1
AS
BEGIN TRAN
SET xact_abort on
UPDATE 賬戶 set 金額=100 WHERE 帳號='帳號'
UPDATE 賬戶 set 金額=100 WHERE 帳號='帳號'
commit tran
GO
2.ADO.NET 級別的事務
這個就是我們在創建訪問數據庫的DBHelper類中經常使用的,如
/// <summary> /// 執行多條SQL語句,實現數據庫事務。 /// </summary> /// <param name="SQLStringList">多條SQL語句</param> public static void ExecuteSqlTran(ArrayList SQLStringList) { using (SqlConnection conn = new SqlConnection(connectionString)) { conn.Open(); SqlCommand cmd = new SqlCommand(); cmd.Connection=conn; SqlTransaction tx=conn.BeginTransaction(); cmd.Transaction=tx; try { for(int n=0;n<SQLStringList.Count;n++) { string strsql=SQLStringList[n].ToString(); if (strsql.Trim().Length>1) { cmd.CommandText=strsql; cmd.ExecuteNonQuery(); } } tx.Commit(); } catch(System.Data.SqlClient.SqlException E) { tx.Rollback(); MyLog.logger.Error("執行多條SQL處理事務錯誤信息:" + E.Message); } } }
3.asp.net 頁面級別的事務
首先在頁面做事務設置,使用Transaction="Required":
<%@ Page Transaction="Required" Language="C#" AutoEventWireup="true" CodeFile="Default2.aspx.cs" Inherits="Default2" %>
然後在後臺中使用ContextUtil.SetComplete();提交事務ContextUtil.SetAbort();取消事務,
try
{
//完成的第一個任務
TaskWork1();
//完成的第二個任務
TaskWork2();
//提交事務
ContextUtil.SetComplete();
}
catch(Exception ex)
{
//如果出現一場則回滾
ContextUtil.SetAbort();
Response.Write(ex.Message);
}
4.企業級服務COM+ 事務
這個使用機制我是第一次使用,我僅在項目中做了一個測試,但是還是沒有正式的使用過,對於我這個菜鳥來說可能在技術上還差的很多。使用方式是這樣:
1)首先引用:using System.EnterpriseServices;如果在見類庫時不能引入可以先導入System.EnterpriseServices這個dll文件
2)讓類繼承ServicedComponent
3)在類頭部加[Transaction(TransactionOption.Required)]
4)給程序添加強名
1.創建密鑰 sn-k c:\key.snk 這個密鑰文件用於對DLL進行簽名,這個key.snk的文件創建需要在目錄下找到sn.exe這個應該是在安裝vs的時候自帶的一個工具吧我找到的它的目錄是在C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin 可以把這個文件拷出來放在一個方便使用的目錄。把生成的key.snk文件放入項目中。
2.在AssemblyInfo.cs引入[assembly: AssemblyKeyFile("..\\key.snk")]
5)手動事務處理
/// <summary>
/// 手動處理事務
/// </summary>
/// <returns></returns>
public string DoTran()
{
try
{
ContextUtil.EnableCommit();
DoWork();
DoWork();
ContextUtil.SetComplete();
return "方法執行成功";
}
catch (Exception)
{
ContextUtil.SetAbort();
return "兩個方法至少有一個執行失敗!";
}
}
6)自動處理事務在方法上加入
[AutoComplete(true)]
private void DoWork()
{
//解決問題的方法
}
這種形式是不是很麻煩,而且性能很低
5.System.Transactions 事務處理 (需要引入System.Transactions這個DLL文件)
public void UseTransactions()
{
using (TransactionScope ts = new TransactionScope())
{
try
{
//處理問題的方法
}
catch (Exception)
{
throw;
}
ts.Complete();
}
}
這種方式非常強大還可以同時連接兩個數據庫
public void UseTransactions()
{
using (TransactionScope ts = new TransactionScope())
{
using (SqlConnection conn = new SqlConnection(strCon))
{
using (SqlConnection conn1 = new SqlConnection(strCon1))
{
}
}
ts.Complete();
}
}
其實還有很多別的強大的功能,我在項目中沒有用到過所以也沒有仔細的研究。還有一個比較有用的是可以控制在操作失敗後仍然執行一個操作然後再次進入事務中,如:如果我們需要在失敗後生成一個失敗的日誌這種就比較實用了使用方式
using (TransactionScope ts = new TransactionScope())
{
using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Suppress))
{
//不受事務控制
}
//受事務控制區域
}