事务-手动事务(ado.net)

来源:互联网 发布:时时彩网络平台 编辑:程序博客网 时间:2024/05/10 19:26

事务类型:

   1,手动事务:用开始和结束事务的显式指令(BEGIN TRANSACTION 和 END TRANSACTION )控制事务边界。从一个事务边界内可以开始第二个被称为嵌套事务的事务。直到所有从属事务提交,其父事务才提交。

   2:自动事务:基于每个组件的声明特性集管理事务边界。事务自动流向被指示参与事务的对象,并跳过被指示在事务外部执行的对象。使用自动事务模型时无法嵌套事务。

分布式事务处理 (TP):分布式事务处理 (TP) 系统旨在协助在分布式环境中跨异类的事务识别资源的事务。

手动事务和 ADO.NET

SQL 客户端和 OLE DB .NET 提供程序在公共语言运行库中支持手动事务。在 ADO.NET 中,这两个 .NET 提供程序都可以用来控制事务。

应使用 ADO.NET 连接对象 Connection.BeginTransaction 开始本地事务。用 Command 对象的 Transaction 属性登记该事务中的命令。使用 Transaction 对象根据事务组件的成功或失败而提交或回滚在数据源做的修改。

登记在默认情况下是自动的,而且可以禁用。如果禁用了自动登记,您可以手动登记。在一个现有分布式事务中使用 Connection.EnlistDistributedTransaction 进行登记。

若要执行事务,请执行下列操作:

  1. 调用 Connection 对象的 BeginTransaction 方法来标记事务的开始。BeginTransaction 方法返回对 Transaction 的引用。该引用将分配给登记在事务中的 Command 对象。
  2. Transaction 对象分配给要执行的 CommandTransaction 属性。如果通过活动的 Transaction 对象对 Connection 执行 Command,但该 Transaction 对象尚未分配给 CommandTransaction 属性,则将引发异常。
  3. 执行所需的命令。
  4. 调用 Transaction 对象的 Commit 方法来完成事务,或调用 Rollback 方法来取消事务。

myConnection.Open();

SqlTransaction myTrans = myConnection.BeginTransaction();

SqlCommand myCommand = myConnection.CreateCommand();
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 (SqlException ex)
  {
    if (myTrans.Connection != null)
    {
      Console.WriteLine("An exception of type " + ex.GetType() +
                        " was encountered while attempting to roll back the transaction.");
    }
  }

分布事务:

如果 Connection 对象确定事务是活动的,它将自动登记在现有的分布式事务中。当打开连接或从连接池中检索连接时,将发生自动事务登记。这种情况,如果在Connection打开后,如果想再将新的的操作(command)登记入事务使不可能的。此时,应禁用自动登记功能:

   sqlserver为在连接字符串中设置Enlist字段为false:Enlist=false

   oledb中为OLE DB Services=-7

此时可以使用 EnlistDistributedTransaction 在事务中登记 Connection

SqlConnection nwindConn = new SqlConnection(".......;Enlist=false;");

SqlCommand cmd = new SqlCommand("......", nwindConn);

...

nwindConn.Open();

ITransaction trans =(ITransaction)ContextUtil.Transaction;//获取当前分布事务

nwindConn.EnlistDistributedTransaction(trans);//之前必须nwindConn.Open();

try
    {
      cmd.ExecuteNonQuery();//执行事务

      ContextUtil.SetComplete();//提交事务
    }
    catch (SqlException e)
    {
     ContextUtil.SetAbort();
    }
    finally
    {
      nwindConn.Close();
    }



原创粉丝点击