zoukankan      html  css  js  c++  java
  • 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已经存在,所以程序出错跳向Catch{ 回滚 },因此ID=3也未被添加!
                tran.Commit();
                SetBind();
            }
            catch
            {
                tran.Rollback();
            }

  • 相关阅读:
    node学习报错之883
    vue-cli4创建项目
    Decorator学习笔记
    合天网安实验室学习笔记----Linux基础
    IDF实验室解题学习笔记1
    QA笑话----杂思
    测试优先
    Python的IDE:Eclipse+PyDev配置
    JS实现浏览器的title闪烁
    JSTL实现分页
  • 原文地址:https://www.cnblogs.com/chenbg2001/p/1604054.html
Copyright © 2011-2022 走看看