程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> c# 事物處理

c# 事物處理

編輯:C#入門知識

以下示例創建一個 OleDbConnection 和一個 OleDbTransaction。它還演示了如何使用 BeginTransaction、Commit 和 Rollback 方法。

public void RunOleDbTransaction(string myConnString)
{
OleDbConnection myConnection = new OleDbConnection(myConnString);
myConnection.Open();
OleDbCommand myCommand = myConnection.CreateCommand();
OleDbTransaction myTrans;

// Start a local transaction
myTrans = myConnection.BeginTransaction(IsolationLevel.ReadCommitted);
// Assign transaction object for a pending local transaction
myCommand.Connection = myConnection;
myCommand.Transaction = myTrans;
try
{
myCommand.CommandText = ""Insert into Region (RegionID, RegionDescription) VALUES (100, "Description")"";
myCommand.ExecuteNonQuery();
myCommand.CommandText = ""Insert into Region (RegionID, RegionDescription) VALUES (101, "Description")"";
myCommand.ExecuteNonQuery();
myTrans.Commit();
Console.WriteLine(""Both records are written to database."");
}
catch(Exception e)
{
try
{
myTrans.Rollback();
}
catch (OleDbException ex)
{
if (myTrans.Connection != null)
{
Console.WriteLine(""An exception of type "" + ex.GetType() +
"" was encountered while attempting to roll back the transaction."");
}
}

Console.WriteLine(""An exception of type "" + e.GetType() +
"" was encountered while inserting the data."");
Console.WriteLine(""Neither record was written to database."");
}
finally
{
myConnection.Close();
}
}

OleDbTransaction.Commit 方法
提交數據庫事務。
public virtual void Commit();
OleDbTransaction.Rollback 方法
從掛起狀態回滾事務。
public virtual void Rollback();
OleDbConnection.BeginTransaction 方法
開始數據庫事務。
public OleDbTransaction BeginTransaction();
以當前的 IsolationLevel 值開始數據庫事務。
public OleDbTransaction BeginTransaction(IsolationLevel);
IsolationLevel 枚舉?
指定連接的事務鎖定行為。 在執行事務時,.NET Framework 數據提供程序使用 IsolationLevel 值。在顯式更改之前,IsolationLevel 保持有效,但是可以隨時對它進行更改。新值在執行時使用,而不是在分析時使用。如果在事務期間更改,服務器的預期行為是,對其余所有語句應用新的鎖定級別。
IsolationLevel成員 ReadCommitted
在正在讀取數據時保持共享鎖,以避免髒讀,但是在事務結束之前可以更改數據,從而導致不可重復的讀取或幻像數據。
OleDbConnection.CreateCommand 方法
創建和返回一個與 OleDbConnection 相關聯的 OleDbCommand 對象。
public OleDbCommand CreateCommand();
OleDbCommand.Connection 屬性
獲取或設置 OleDbCommand 的此實例使用的 OleDbConnection。
public OleDbConnection Connection {get; set;}

如何在.NET中實現事務(1)
 
如何在.NET中實現事務機制呢? 通常可以使用2種方式: 直接寫入到sql 中;使用ADO.NET 實現。下面依次作一下介紹:
方法1:直接寫入到sql 中
使用 BEGIN TRANS, COMMIT TRANS, ROLLBACK TRANS 實現:
例如
BEGIN TRANS
DECLARE @orderDetailsError int, @productError int
DELETE FROM ""Order Details"" WHERE ProductID=42
SELECT @orderDetailsError = @@ERROR
DELETE FROM Products WHERE ProductID=42
SELECT @productError = @@ERROR
IF @orderDetailsError = 0 AND @productError = 0
COMMIT TRANS
ELSE
ROLLBACK TRANS
這種方法比較簡單,具體可以查閱相關sql server 幫助

方法2 :使用ADO.NET 實現,使用這種方式的優點是可以在中間層來管理事務,當然你也可以選擇在數據層來實現。
SqlConnection 和OleDbConnection 對象有一個 BeginTransaction 方法,它可以返回 SqlTransaction 或者OleDbTransaction 對象。而且這個對象有 Commit 和 Rollback 方法來管理事務,具體例子如下:

cnNorthwind.Open()
Dim trans As SqlTransaction = cnNorthwind.BeginTransaction()
Dim cmDel As New SqlCommand()
cmDel.Connection = cnNorthwind
cmDel.Transaction = trans

Try
cmDel.CommandText = _
""DELETE [Order Details] WHERE ProductID = 42""
cmDel.ExecuteNonQuery()
cmDel.CommandText = ""DELETE Products WHERE ProductID = 42""
cmDel.ExecuteNonQuery()
trans.Commit()

Catch Xcp As Exception
trans.Rollback()
Finally
cnNorthwind.Close()
End Try

Ok,通過上面的例子可以實現與方法1同樣的效果。

並發問題:

如果沒有鎖定且多個用戶同時訪問一個數據庫,則當他們的事務同時使用相同的數據時可能會發生問題。並發問題包括: 丟失或覆蓋更新,未確認的相關性(髒讀),不一致的分析(非重復讀),幻像讀。但是如何來避免數據讀取時髒讀等問題出現呢?
 
二、事務實例
using(SqlTransaction trans = conn.BeginTransaction())
{
  try
  {
 //循環進行信息的插入
 for(int count = 0; count < applyInfo.Length; count ++)
 {
   //聲明參數並賦值
   SqlParameter[] parms =
{ Database.MakeInParam (""@Stu_ID"",System.Data.SqlDbType.VarChar,11,applyInfocount].StuID),
Database.MakeInParam""@Bank_Name"",System.Data.SqlDbType.VarChar,50,applyInfo[count].BankName),  Database.MakeInParam""@Apply_Loan_Money"",System.Data.SqlDbType.Money,8,applyInfo[count].ApplyLoanMoney), Database.MakeInParam(""@Apply_Loan_Year"",System.Data.SqlDbType.VarChar,20,applyInfo[count].ApplyLoanYear),  Database.MakeInParam""@Apply_Year"",System.Data.SqlDbType.Char,6,applyInfo[count].ApplyYear),       Database.MakeInParam(""@Apply_Length"",System.Data.SqlDbType.Int,4,applyInfo[count].ApplyLength),       Database.MakeInParam(""@Apply_Pass"",System.Data.SqlDbType.Char,1,applyInfo[count].ApplyPass),
Database.MakeInParam(""@Apply_Remark"",System.Data.SqlDbType.VarChar,100,applyInfo[count].ApplyRemark)
        };
  //執行新增操作
  SqlHelper.ExecuteNonQuery(trans,CommandType.StoredProcedure, ""ApplyInfo_Create"", parms);
}
      //未出現錯誤,則提交事務
   trans.Commit();
   return true;
   }
       catch(Exception ex)
   {
  //出錯則回滾
  trans.Rollback();
  throw ex;
       }
 }
四、注意事項
  事務的定義必須在連接打開後,提交必須在關閉以前
  使用事務時必須即是把事務添加到sqlCommand中去。

另外,以下是一段在LINQ中實現的事務:

 

if (ctx.Connection != null) ctx.Connection.Open();
        DbTransaction tran = ctx.Connection.BeginTransaction();
        ctx.Transaction = tran;
        try
        {
            CreateTest(new tbTest {ID=3,Name="妹子" });
            CreateTest(new tbTest {ID=2,Name="哥們" });//因為ID=2已經存在,所以程序出錯跳向Catc

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved