`

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 事务处理方法技巧 ADO.NET 事务处理方法是指在编程中使用的一种机制,用于保证数据一致性和完整性。事务是一组不可分的 SQL 语句,在编程中也是很难解决的一个问题。ADO.NET 事务处理方法提供...

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

    《基于ADO.NET与SQL2005的学生管理系统详解》 在信息技术日新月异的今天,学生管理系统已经成为教育机构日常管理的重要工具。本系统利用ADO.NET技术和SQL Server 2005数据库,实现了对学生的全面信息化管理,为教育...

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

    本文将深入探讨三种常见的.NET框架下的数据库访问技术:ADO.NET SQL、LINQ to SQL以及ADO.NET Entity Framework(EF),并重点分析它们在数据库连接性能上的差异,特别是在插入和读取操作,包括模糊检索方面的表现。...

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

    通过分析和学习这些源代码示例,你将能够深入了解ADO.NET 4的工作原理,如何有效地处理数据连接、查询、事务,以及如何将数据绑定到用户界面。无论是初学者还是经验丰富的开发者,都能从中受益,提升自己的数据库...

    ADO.NET 4从入门到精通

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

    ADO.NET 全面解析ADO.NET

    ADO.NET是Microsoft开发的一种用于访问关系数据库的数据访问技术,它为.NET Framework应用程序提供了一套全面的数据访问组件。本文将深入探讨ADO.NET的核心概念、对象模型和数据操作。 首先,我们来看ADO.NET的设计...

    ado.net面试题

    6. **事务处理**:ADO.NET 支持在连接级别和数据适配器级别的事务控制,确保数据一致性。 7. **XML集成**:ADO.NET 与XML紧密结合,可以轻松地在XML和关系数据之间转换,增强了数据的可移植性和互操作性。 8. **...

    ADO.NET本质论.rar

    7. 错误处理和事务:讨论在ADO.NET中处理数据库错误的方法,以及如何使用Transaction对象进行事务管理。 8. 性能优化:提供关于提高ADO.NET应用程序性能的技巧和最佳实践。 9. 新特性与变化:如果书籍较新,可能会...

    《ADO.NET专业项目实例开发》源代码

    5. **事务处理**:在ADO.NET中,`SqlTransaction`类用于管理数据库事务。通过开启一个事务,可以确保一系列数据库操作要么全部成功,要么全部失败,实现数据的一致性。 6. **存储过程**:源代码可能包含调用存储...

    ADO.NET教程(适合新手)

    本教程将详细介绍以上概念,通过实例演示如何创建数据库连接、执行查询、操作数据、处理事务以及使用数据绑定等,帮助初学者快速掌握ADO.NET的基本用法。在学习过程中,读者将能够构建自己的数据访问层,为实际项目...

    ADO.NET核心技术(我看过最好的ADO。NET书)

    ### ADO.NET核心技术详解 #### 一、ADO.NET概述 ADO.NET是一组包含在.NET框架中的库,专门用于在.NET应用程序的各种数据存储之间进行通信。它不仅能够作为一个强大的、层次化的数据缓存来使用,还支持离线处理数据...

    自做的ADO.NET项目 借阅图书

    《自做的ADO.NET项目——借阅图书》 在信息技术领域,数据库管理是不可或缺的一部分,而ADO.NET作为.NET框架中用于数据库交互的重要组件,为开发者提供了高效、强大的数据访问能力。本项目“借阅图书”正是基于ADO...

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

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

    ADO.NET数据库访问技术案例教程

    接下来,我们将探讨ADO.NET的事务处理(Transaction)和批处理(Batching)。事务处理确保数据操作的一致性和完整性,允许在一组操作中进行回滚或提交。批处理则允许一次性执行多个命令,提高数据处理的效率。 ADO...

    基于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本质论.pdf

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

    ADO.NET官方参考文档2021-09.pdf

    ADO.NET 是 .NET Framework 中用于访问关系数据库的关键组件,它提供了与各种数据源(如 SQL Server、Oracle 等)交互的灵活性。在2021-09版的官方参考文档中,主要关注了DataSet、DataTable、DataView这三个核心类...

    Professional ADO .NET Programming

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

    ADO.net大数据量操作数据库实验

    本实验“ADO.NET大数据量操作数据库实验”聚焦于如何高效地在SQL Server中存储和处理大量数据。实验环境基于Visual Studio 2015(VS2015)和SQL Server 2008,采用多种方法来演示批量数据插入,包括常规方法、Bulk ...

Global site tag (gtag.js) - Google Analytics