`

ADO.NET事务拾遗

阅读更多
代码段1:
using (SqlConnection conn1 = new SqlConnection(connString))
{
  if (conn1.State == ConnectionState.Closed)
      conn1.Open();
   SqlTransaction trans = conn1.BeginTransaction(IsolationLevel.ReadUncommitted);              
   try
   { 
      SqlCommand cmd1 = new SqlCommand();
      cmd1.Connection = conn1;
      cmd1.CommandText = insertString1;//插入语句1
      cmd1.Transaction = trans;
      cmd1.ExecuteNonQuery();
      cmd1.CommandText = insertString2;//插入语句2
      cmd1.Transaction = trans;
      cmd1.ExecuteNonQuery();

      SqlCommand cmd2 = new SqlCommand(selectString, conn1);//查询语句
      SqlDataAdapter sda = new SqlDataAdapter(cmd2);
      DataSet ds =new DataSet();
      sda.Fill(ds);

      trans.Commit();                    
    }
    catch(SqlException ex){
       trans.Rollback();
        Console.WriteLine(ex.Message);
    }
}

说明:insertString1、insertString2和selectString操作的是同一张表
1.运行这段代码,到第21行(sda.Fill(ds))会出现异常:“如果分配给命令的连接位于本地挂起事务中,ExecuteReader 要求命令拥有事务。命令的 Transaction 属性尚未初始化。”
原因:SqlDataAdapter在填充数据时使用SqlDataReader读取数据,事务是基于数据库连接的,cmd1和cmd2使用的是同一连接,执行完cmd1后,事务处于挂起状态,还未提交。为了保持事务的完整性(其实这个地方是原子性的体现),要求新的cmd2必须也使用同一事务。
代码段2:将代码段1稍作修改,使cmd2使用新的连接conn2
using (SqlConnection conn1 = new SqlConnection(connString))
{
  if (conn1.State == ConnectionState.Closed)
      conn1.Open();
   SqlTransaction trans = conn1.BeginTransaction(IsolationLevel.ReadUncommitted);              
   try
   { 
      SqlCommand cmd1 = new SqlCommand();
      cmd1.Connection = conn1;
      cmd1.CommandText = insertString1;//插入语句1
      cmd1.Transaction = trans;
      cmd1.ExecuteNonQuery();
      cmd1.CommandText = insertString2;//插入语句2
      cmd1.Transaction = trans;
      cmd1.ExecuteNonQuery();
      //下面使cmd2使用新的连接conn2
      using (SqlConnection conn2 = new SqlConnection(connString))
      {
        SqlCommand cmd2 = new SqlCommand(selectString, conn2);
        SqlDataAdapter sda = new SqlDataAdapter(cmd2);
        DataSet ds = new DataSet();
        sda.Fill(ds);
      }

      trans.Commit();                    
    }
    catch(SqlException ex){
       trans.Rollback();
        Console.WriteLine(ex.Message);
    }
}

在 sda.Fill(ds)时会抛出异常:“ 超时时间已到。在操作完成之前超时时间已过或服务器未响应”
原因:
在SQL Server 2005中运行下面的脚本,可以获得锁的信息:
select request_session_id,
	   resource_type,
       resource_database_id,
       resource_description ,
	   resource_associated_entity_id,
	   request_mode,
	   request_status       
from sys.dm_tran_locks

会发现有两个会话(SQl Server中的两个进程)发生了冲突,会话1请求了一个排它锁,而会话2一直在等待同一资源的共享锁,因此会话2被阻塞,形成了死锁的情况,过了程序设置的超时时间,SQLServer2005会自动终止操作,在C#中就会捕捉到超时的异常。(虽然会话1中事务的隔离级别已手动设置为未提交读ReadUncommitted,但是回话2中默认隔离级别为已提交读ReadCommited,所以会话2依然会等待会话释放排它锁)

总结:以上例子仅供说明之用,在使用事务时,要根据业务设计好数据库操作顺序,并且恰当的设置隔离级别,避免此种情况的出现。
分享到:
评论
1 楼 风过有声 2011-04-21  
好 

相关推荐

    轻轻松松掌握ADO.NET事务处理方法技巧

    这里介绍了ADO.NET事务处理方法BeginTrans:开始1个事务、CommitTrans:提交事务,将事务中的操作写入数据源、RollBackTrans:滚回事务,取消操作。

    ADO.NET 4从入门到精通

    《ADO.NET 4从入门到精通》主要内容简介:ADO.NET是windows开发平台上的核心数据技术之一。《ADO.NET 4从入门到精通》是microsoft ADO.NET 4的入门教程,旨在帮助visual basic和c#开发人员了解ADO.NET及相关技术的...

    ADO.Net助手V1.00---一个获取ADO.Net连接字符串,测试SQL命令的辅助软件

    ADO.Net助手是一个获取ADO.Net连接字符串(支持Access,SQLite,SQLServer,MySQL和ORACLE),测试SQL命令,存储过程和数据库之间互导数据的辅助软件。ADO.Net助手还可以用来以插入SQL语句形式导出导入记录,目前提供了...

    ADO.NET sql、LINQ to sql、ADO.NET Entity Framework(EF)数据库连接性能比较

    数据ADO.NET sql、LINQ to sql、ADO.NET Entity Framework(EF)数据库连接性能比较,主要比较了插入与读取的时间,读取里可以进行模糊检索

    基于ADO.NET的用户登陆与注册系统

    摘要:基于ASP.NET的WEB应用程序项目,使用程序语言C#,利用ADO.NET访问数据库,实现一个简易的用户登陆注册系统。主要实现的功能有用户登陆、用户注册、找回密码,... 关键字:ASP.NET;ADO.NET;WEB;vs2010;数据库

    ADO.NET考试上机题

    ADO.NET考试上机题ADO.NET考试上机题ADO.NET考试上机题ADO.NET考试上机题ADO.NET考试上机题ADO.NET考试上机题ADO.NET考试上机题ADO.NET考试上机题ADO.NET考试上机题ADO.NET考试上机题ADO.NET考试上机题ADO.NET考试...

    ADO.NET数据库访问技术详细资料

    C#与数据库访问技术 ADO.NET(ActiveX Data Object.NET)是Microsoft公司开发的用于数据库连接的... ADO.NET还提供了对XML格式文档的支持,所以通过ADO.NET组件可以方便地在异构环境的项目间读取和交换数据。 ......

    ADO.NET自己封装SqlHelper类

    ADO.NET自己封装SqlHelper类 1、简单封装 2、传递参数封装 3、参数可变封装

    ado.net操作oracle简单参数化sql操作

    关于ado.net简单的参数化查询,操作的是oracle数据库!关于ado.net简单的参数化查询,操作的是oracle数据库!

    Professional ADO .NET Programming

    Professional ADO .NET Programming Professional ADO .NET Programming Professional ADO .NET Programming Professional ADO .NET Programming

    学生管理系统+ADO.NET+SQL2005

    学生管理系统源码,ADO.NET进行增删改查学生基本和系别信息,适合毕业设计。

    ADO.NET 高级编程

    ADO.NET 高级编程,深入剖析ADO.NET类

    Microsoft ADO.NET Step by Step

    Table of Contents Microsoft ADO.NET Step by Step Introduction Part I - Getting Started with ADO.NET Chapter 1 - Getting Started with ADO.NET ...

    ADO.Net数据库访问(代码示例)

    ADO.Net数据库访问(代码示例),介绍了ADO.Net数据库访问的核心技术

    ADO.NET本质论

    讲解了数据结构,演示了如何用ADO.NET来解决具体的数据访问问题。重点讨论了ADO.NET如何有效地平衡"功能的泛化"和"执行效率",以及它如何解决对扩展性、并发性和可靠性的要求。针对其他数据访问API(包括OLE DB,ADO...

    ADO.NET 4从入门到精通源代码

    ADO.NET 4从入门到精通源代码 里面有 未完成的和已完成的 源代码示例

    Pro ADO.NET Data Services: Working with RESTful Data

    Pro ADO.NET Data Services: Working with RESTful Data Paperback: 336 pages Publisher: Apress; 1 edition (December 2, 2008) Language: English ISBN-10: 143021614X ISBN-13: 978-1430216148 Format: PDF You...

    ADO.NET高级编程

    ADO.NET是Microsoft最新推出的数据访问技术。作为.NET框架的一部分,ADO.NET绝不仅仅是前一版本ADO的简单升级。ADO.NET提供了一组.NET类,这些类不仅可以帮助我们对各种数据源进行高效访问,使我们能够对数据...

    ADO.NET事务.docx

    ADO.NET事务.docx

    ADO.net操作数据库总结

    ADO.net操作数据库总结,包括SqlConnection、SqlCommand等

Global site tag (gtag.js) - Google Analytics