.net中的4種事務總結

在一個MIS系統中,沒有用事務那就絕對是有問題的,要麼就只有一種情況:你的系統實在是太小了,業務業務邏輯有隻要一步執行就可以完成了。因此掌握事務處理的方法是很重要,進我的歸類在.net中大致有以下4種事務處理的方法。大家可以參考一下,根據實際選擇適當的事務處理。
1 SQL事務
    sql事務是使用SQL server自身的事務:在存儲過程中直接使用Begin Tran,Rollback Tran,Commit Tran實現事務:
優點:執行效率最佳
限制:事務上下文僅在數據庫中調用,難以實現複雜的業務邏輯。
Demo:(所有demo,都以SQL Server自帶的Northwind數據的表Region爲例)

CREATE PROCEDURE dbo.SPTransaction
    (
    
@UpdateID int,
    
@UpdateValue nchar(50),
    
@InsertID int,
    
@InsertValue nchar(50)
    )
AS
begin Tran
Update Region  Set RegionDescription=@UpdateValue where RegionID=@UpdateID

insert into Region Values (@InsertID,@InsertValue)

declare @RegionError int
select @RegionError=@@error
if(@RegionError=0)
COMMIT Tran
else
ROLLBACK Tran
GO

/// <summary>
        
/// SQL事務:
        
/// </summary>

        public void SQLTran()
        
{
            SqlConnection conn 
= new SqlConnection("Data Source=127.0.0.1;Initial Catalog=Northwind;Persist Security Info=True;User ID=sa;Password=123;");
            SqlCommand cmd 
= new SqlCommand();
            cmd.CommandText 
= "SPTransaction";
            cmd.CommandType 
= CommandType.StoredProcedure;
            cmd.Connection 
= conn;
            conn.Open();
            SqlParameter[] paras
= new SqlParameter[]{
                                        
new SqlParameter ("@UpdateID",SqlDbType.Int,32),
                                        
new SqlParameter ("@UpdateValue",SqlDbType .NChar,50),
                                        
new SqlParameter ("@InsertID",SqlDbType.Int ,32),
                                        
new SqlParameter ("@InsertValue",SqlDbType.NChar ,50)}
;
            paras[
0].Value = "2";
            paras[
1].Value = "Update Value1";
            paras[
2].Value = "6";
            paras[
3].Value = "Insert Value1";
            
foreach (SqlParameter para in paras )
            
{
                cmd.Parameters.Add(para);
            }

            cmd.ExecuteNonQuery();   
        }

2 ADO.net事務
   Ado.net事務可能是大家一般都用的
 優點:簡單,效率和數據庫事務差不多。
 缺點:事務不能跨數據庫,只能在一個數據庫連接上。如果是兩個數據庫上就不能使用該事務了。
Demo:

/// <summary>
        
/// 一般的ADO.net 事務
        
/// </summary>

        public void ADONetTran1()
        
{
            SqlConnection conn 
= new SqlConnection("Data Source=127.0.0.1;Initial Catalog=Northwind;Persist Security Info=True;User ID=sa;Password=123;");
            SqlCommand cmd 
= new SqlCommand();
            
try
            
{
                cmd.CommandText 
= "Update Region Set RegionDescription=@UpdateValue where RegionID=@UpdateID";
                cmd.CommandType 
= CommandType.Text;
                cmd.Connection 
= conn;
                conn.Open();
                SqlParameter[] paras 
= new SqlParameter[]{
                                        
new SqlParameter ("@UpdateID",SqlDbType.Int,32),
                                        
new SqlParameter ("@UpdateValue",SqlDbType .NChar,50)}
;
                paras[
0].Value = "2";
                paras[
1].Value = "Update Value12";

                
foreach (SqlParameter para in paras)
                
{
                    cmd.Parameters.Add(para);
                }

                
//開始事務
                cmd.Transaction = conn.BeginTransaction();
                cmd.ExecuteNonQuery();


                cmd.CommandText 
= "insert into Region values(@InsertID,@InsertValue)";
                cmd.CommandType 
= CommandType.Text;

                paras 
= new SqlParameter[]{
                                        
new SqlParameter ("@InsertID",SqlDbType.Int ,32),
                                        
new SqlParameter ("@InsertValue",SqlDbType.NChar ,50)}
;
                paras[
0].Value = "7";
                paras[
1].Value = "Insert Value";

                cmd.Parameters.Clear();
                
foreach (SqlParameter para in paras)
                
{
                    cmd.Parameters.Add(para);
                }

                
                cmd.ExecuteNonQuery();
                
//提交事務
                cmd.Transaction.Commit();
            }

            
catch
            
{
                
//回滾事務
                cmd.Transaction.Rollback();
                
throw;
            }

            
finally
            
{
                conn.Close();
            }


        }
3 TransactionScope事務
  TransactionScope事務類,它可以使代碼塊成爲事務性代碼。並自動提升爲分佈式事務
 優點:實現簡單,同時能夠自動提升爲分佈式事務
Demo:

 /// <summary>
        
/// TransactionScope事務:可自動提升事務爲完全分佈式事務的輕型(本地)事務。 
        
/// 使用時要保證MSDTC服務(控制分佈事務)是開啓的可以使用:net start msdtc命令開啓服務;
        
/// </summary>

        public void ADONetTran2()
        
{
             SqlConnection conn 
= new SqlConnection("Data Source=127.0.0.1;Initial Catalog=Northwind;Persist Security Info=True;User ID=sa;Password=123;");
             SqlCommand cmd 
= new SqlCommand();
            
try
            
{
              
                
using (System.Transactions.TransactionScope ts = new TransactionScope())
                
{
                    
                    cmd.CommandText 
= "Update Region Set RegionDescription=@UpdateValue where RegionID=@UpdateID";
                    cmd.CommandType 
= CommandType.Text;
                    cmd.Connection 
= conn;
                    conn.Open();
                    SqlParameter[] paras 
= new SqlParameter[]{
                                        
new SqlParameter ("@UpdateID",SqlDbType.Int,32),
                                        
new SqlParameter ("@UpdateValue",SqlDbType .NChar,50)}
;
                    paras[
0].Value = "2";
                    paras[
1].Value = "Update Value12";

                    
foreach (SqlParameter para in paras)
                    
{
                        cmd.Parameters.Add(para);
                    }

                    cmd.ExecuteNonQuery();


                    cmd.CommandText 
= "insert into Region values(@InsertID,@InsertValue)";
                    cmd.CommandType 
= CommandType.Text;

                    paras 
= new SqlParameter[]{
                                        
new SqlParameter ("@InsertID",SqlDbType.Int ,32),
                                        
new SqlParameter ("@InsertValue",SqlDbType.NChar ,50)}
;
                    paras[
0].Value = "8";
                    paras[
1].Value = "Insert Value";

                    cmd.Parameters.Clear();
                    
foreach (SqlParameter para in paras)
                    
{
                        cmd.Parameters.Add(para);
                    }


                    cmd.ExecuteNonQuery();
                    
//提交事務
                    ts.Complete();
                }

            }

            
catch
            
{
                
throw;
            }

            
finally
            
{
                conn.Close();
            }


        }
4 COM+事務
  在分佈式應用程序中,往往要同時操作多個數據庫,使用數據庫事務就不能滿足業務的要求了。在COM+中,提供完整的事務處理服務。很方便處理多個數據庫上的事務。
Demo:

/**//// <summary>
        
/// COM+事務
        
/// </summary>

        public void ComTran()
        
{
            SqlConnection conn 
= new SqlConnection("Data Source=127.0.0.1;Initial Catalog=Northwind;Persist Security Info=True;User ID=sa;Password=123;");
            SqlCommand cmd 
= new SqlCommand();
            ServiceConfig sc 
= new ServiceConfig();

            
//指定事務類型
            sc.Transaction = TransactionOption.Required;
            
//設置啓動跟蹤
            sc.TrackingEnabled = true;
            
//創建一個上下文,該上下文的配置由作爲 cfg 參數傳遞的 ServiceConfig 對象來指定。
            
//隨後,客戶端和服務器端的策略均被觸發,如同發生了一個方法調用。
            
//接着,新的上下文被推至上下文堆棧,成爲當前上下文
            ServiceDomain.Enter(sc);
            
try
            
{
                    cmd.CommandText 
= "Update Region Set RegionDescription=@UpdateValue where RegionID=@UpdateID";
                    cmd.CommandType 
= CommandType.Text;
                    cmd.Connection 
= conn;
                    conn.Open();
                    SqlParameter[] paras 
= new SqlParameter[]{
                                        
new SqlParameter ("@UpdateID",SqlDbType.Int,32),
                                        
new SqlParameter ("@UpdateValue",SqlDbType .NChar,50)}
;
                    paras[
0].Value = "2";
                    paras[
1].Value = "Update Value22";

                    
foreach (SqlParameter para in paras)
                    
{
                        cmd.Parameters.Add(para);
                    }

                    cmd.ExecuteNonQuery();


                    cmd.CommandText 
= "insert into Region values(@InsertID,@InsertValue)";
                    cmd.CommandType 
= CommandType.Text;

                    paras 
= new SqlParameter[]{
                                        
new SqlParameter ("@InsertID",SqlDbType.Int ,32),
                                        
new SqlParameter ("@InsertValue",SqlDbType.NChar ,50)}
;
                    paras[
0].Value = "9";
                    paras[
1].Value = "Insert Value";

                    cmd.Parameters.Clear();
                    
foreach (SqlParameter para in paras)
                    
{
                        cmd.Parameters.Add(para);
                    }


                    cmd.ExecuteNonQuery();

                    
//提交事務
                    ContextUtil.SetComplete();
            }

            
catch
            
{
                
//回滾事務
                ContextUtil.SetAbort();
                
throw;
            }

            
finally
            
{
                conn.Close();
                
//觸發服務器端的策略,隨後觸發客戶端的策略,如同一個方法調用正在返回。
                
//然後,當前上下文被彈出上下文堆棧,調用 Enter 時正在運行的上下文成爲當前的上下文。
                ServiceDomain.Leave();
            }


        }

在.net中還有些也能進行事務處理,如web Service中

需要特別補充的是:
如果你使用的是分佈事務(TransactionScope事務和COM+事務),在默認情況下你是要重新配置安裝SQL Server數據庫服務器和訪問數據庫的客戶端的.(如果沒有配置運行會出現以下錯誤:該夥伴事務管理器已經禁止了它對遠程/網絡事務的支持。 (異常來自 HRESULT:0x8004D025)
)下面是MSDN上關於配置分佈式事務的一段原話:
配置分佈式事務
要啓用分佈式事務,可能需要通過網絡啓用 MS DTC,以便在使用應用了最新的 Service Pack 的較新操作系統(例如 Windows XP 或 Windows 2003)時使用分佈式事務。如果啓用了 Windows 防火牆(Windows XP Service Pack 2 的默認設置),必須允許 MS DTC 服務使用網絡或打開 MS DTC 端口。
實際怎麼配置呢,經過我的實際使用:大致如下:打開'控制面板'->'管理工具'->'組件服務',點開'組件服務'->'計算機'->'我的電腦',在'我的電腦'上右擊屬性,點'MSDTC',然後點'安全性配置'。作爲數據庫的服務器的配置如下:

而訪問數據庫的客戶端的配置和服務器端的稍有些差別:


在設置完上面的還有使防火牆MS DTC 服務使用網絡或打開 MS DTC 端口:運行netsh firewall set allowedprogram %windir%/system32/msdtc.exe MSDTC enable命令就可以了

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