C#交易處理

來源:互聯網
上載者:User
以下樣本建立一個 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已經存在,所以程式出錯跳向Catch{ 復原 },因此ID=3也未被添加!
            tran.Commit();
            SetBind();
        }
        catch
        {
            tran.Rollback();
        }

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.