Is this a MS EnterLib DAAB BUG or not?

开门见山,使用MS Enterprise Library的DAAB(Data Access Application Block)获取数据时抛出异常。具体场景如下,通过Database对象的ExecuteReader执行两段Select语句,前一句是不合法的,后一句是正确的。为了避免第一次执行出错导致程序的终止,特意将其放到Try/Catch酷快中。两次数据库操作通过TrsanctionScope的形式纳入同一个Transaction中,具体的代码如下所示。

   1: class Program
   2: {
   3:     static void Main()
   4:     {
   5:  
   6:         string invalidSql = "SELECT * FROM {InvalidTable}";
   7:         string validSql = "SELECT * FROM {ValidTable}";
   8:  
   9:  
  10:         Database db = DatabaseFactory.CreateDatabase();
  11:         using (TransactionScope scope = new TransactionScope())
  12:         {
  13:             DbCommand commandWithInvalidSql = db.GetSqlStringCommand(invalidSql);
  14:             DbCommand commandWithValidSql = db.GetSqlStringCommand(validSql);
  15:  
  16:             try
  17:             {
  18:                 db.ExecuteReader(commandWithInvalidSql);
  19:             }
  20:             catch
  21:             { }
  22:  
  23:             db.ExecuteReader(commandWithValidSql);
  24:         }
  25:     }
  26: } 

但是在执行第二个ExecuteReader方法的时候却抛出如下一个InvalidOperationException(如下图),错误消息为:“ExecuteReader requires an open and available Connection. The connection's current state is closed.”

原因出在这里:在ExecuteReader中,相应的ADO.NET代码放在try|catch中,当异常抛出后,相应的DbConnect会被关闭。但是由于在我的代码中,两次ExecuteReader的调用是在一个相同的Ambient Transaction中执行的,DAAB在内部采用相同的DbTransaction执行这两项操作,当执行第一项操作时,由于出现异常导致DbConnect关闭,使用相同DbConnect的第二项操作肯定会失败。

   1: public virtual IDataReader ExecuteReader(DbCommand command)
   2: {
   3:     ConnectionWrapper wrapper = GetOpenConnection(false);
   4:  
   5:     try
   6:     {
   7: //
   8: // JS-L: I moved the PrepareCommand inside the try because it can fail.
   9: //
  10: PrepareCommand(command, wrapper.Connection);
  11:  
  12: //
  13: // If there is a current transaction, we'll be using a shared connection, so we don't
  14: // want to close the connection when we're done with the reader.
  15: //
  16: if (Transaction.Current != null)
  17:     return DoExecuteReader(command, CommandBehavior.Default);
  18: else
  19:     return DoExecuteReader(command, CommandBehavior.CloseConnection);
  20:     }
  21:     catch
  22:     {
  23: wrapper.Connection.Close();
  24: throw;
  25:     }
  26: } 
  27:  

我不清楚微软在设计的时候,是因为没有考虑到这种场景呢,还是不得以而为之,或者是出于其他因素的考虑,大家有何见解。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏葡萄城控件技术团队

ASP.NET 5系列教程(七)完结篇-解读代码

在本文中,我们将一起查看TodoController 类代码。 [Route] 属性定义了Controller的URL 模板: [Route("api/[con...

2195
来自专栏大内老A

谈谈分布式事务之三: System.Transactions事务详解[上篇]

在.NET 1.x中,我们基本是通过ADO.NET实现对不同数据库访问的事务。.NET 2.0为了带来了全新的事务编程模式,由于所有事务组件或者类型均定义在Sy...

2268
来自专栏一个会写诗的程序员的博客

WebDriver 的协议标准 W3C

https://github.com/Jason-Chen-2017/go-selenium

3522
来自专栏个人随笔

C#连接操作MySQL数据库 帮助类

2013
来自专栏linjinhe的专栏

LevelDB:使用介绍

Get 接口和 Put 接口比较像,除了 leveldb::ReadOptions 参数是用来控制读操作的,具体见链接指向的代码。

7315
来自专栏.NET开发者社区

一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](六)

又是星期五,很兴奋,很高兴,很high…啦啦啦。。。 Rector在图享网又和大家见面啦!!!上一篇《一步一步创建ASP.NET MVC5程序[Reposito...

2617
来自专栏程序员的SOD蜜

一行代码调用实现带字段选取+条件判断+排序+分页功能的增强ORM框架

问题:3行代码 PDF.NET 是一个开源的数据开发框架,它的特点是简单、轻量、快速,易上手,而且是一个注释完善的国产开发框架,受到不少朋友的欢迎,也在我们公...

3089
来自专栏菩提树下的杨过

Enterprise Library 4.1学习笔记2----数据访问程序块

Data Access Application Block 其实个人感觉相当于另一个版本的dbHelper 废话不多说,先看下如何使用: 1.引用Microso...

19010
来自专栏王磊的博客

iBatis for net 框架使用

简介:ibatis 一词来源于“internet”和“abatis”的组合,是一个由Clinton Begin在2001年发起的开放源代码项目,到后面发展的版本...

35010
来自专栏分布式系统和大数据处理

在Web站点中创建和使用Rss源

Rss是将你Web站点的内容与其他人分享的标准方式。Rss代表着:Really Simple Syndication。它不过是一个标准化的XML标记,用于描述你...

882

扫码关注云+社区

领取腾讯云代金券