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:  

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


作者:蒋金楠
微信公众账号:大内老A
微博:www.weibo.com/artech
如果你想及时得到个人撰写文章以及著作的消息推送,或者想看看个人推荐的技术资料,可以扫描左边二维码(或者长按识别二维码)关注个人公众号(原来公众帐号蒋金楠的自媒体将会停用)。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

原文链接

时间: 2024-09-22 20:32:44

Is this a MS EnterLib DAAB BUG or not?的相关文章

WCF技术剖析之七:如何实现WCF与EnterLib PIAB、Unity之间的集成

在这之前,我写过深入介绍MS EnterLib PIAB的文章(参阅<MS Enterprise Library Policy Injection Application Block 深入解析[总结篇]>),也写过WCF与PIAB的集成(参阅:<WCF后续之旅(8):通过WCF Extension 实现与MS Enterprise Library Policy Injection Application Block 的集成>).WCF与Unity的集成(参阅<WCF后续之旅(

利用Winsock下载文件(支持断点续传)

下载 第一步,建立工程,引用Winsock(Visual Basic最好打SP6,否则MS有一个Bug),在此省略 第二步,具体实现代码步骤1:发送请求说明:(1)这里简单采用了判断是否已经有同名文件表示是否要断点续传(2)下载的地址,大小和已下载字节数也只是简单地存在ini文件中,更安全的做法本文不作讨论有兴趣的朋友可以联系我 '--------------------------------------------------------------------------------'  

如何让用户在关闭浏览器后,使ASP.Net程序,在1分钟后,Session失效

asp.net|session|程序|浏览器   在写一个客户的B/S结构应用程序时,突然发现一个技巧,不知道是否是MS的一个BUG,给相关的有研究的朋友原先考虑写一个检查Session的类,Session失效后,必须转向登陆页面,可每一个调用该类的页面,在不同的WEB路径下,所以转到登陆页面的URL都不同,每个页面都要调用和设置登陆页面路径,所以实际应用就放弃了这一想法后来考虑到不如写一个检查Session失效的页面,由客户端每一秒都刷新一下,就可以在一个页面中调用,但通过FRAME嵌入该AS

Excel单元格格式选择货币格式US$时变成US$¥

症状:用户在设定单元格格式选择货币格式US$时变成US$¥,多了个人民币元的符号--¥,如图: 原因:MS Office的Bug(Excel 2003 SP3 ) 解决方法:打补丁office2003-KB952208-GLB, 下载地址:http://thehotfixshare.net/board/index.php?autocom=downloads&req=download&code=confirm_download&id=6769 查看本栏目更多精彩内容:http://w

让服务器支持中文文件名下载的设置方法_服务器

这个问题讨论过很多次了,确实是ms的大bug,出现在远东语言版的iis上.除了骂鳖儿该死之外,你有五个选择: 1.   换用其他的web server,比如apache.   [强烈推荐本方法] 2.   不使用中文做文件名,可以用拼音来替代.   [推荐] 3.   使用中英文混合文件名(据称能回避bug,但未经完全测试,不能保证所有情况下都能正确访问)   [不推荐] 4.   等ms出补丁   [没希望了,不知道多久了,也没看到补丁] 5.   强制所有的用户都仅使用直接以本地中文编码发送

使用MS Enterprise Library的DAAB获取数据时抛出异常

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

EnterLib PIAB又一个BUG?[续]——这是一个致命的BUG

在<EnterLib PIAB又一个BUG?>这篇文章中我们谈到:当我们通过应用DependencyAttribute特性定义需要自动注入的属性的时候,当这个属性为接口.抽象类或者没有定义无参的构造函数,无论我们调用PolicyInjection的Create方法去创建一个新的对象,还是调用Wrap方法对现有对象进行封装,都会抛出一个ResolutionFailedException异常.之后根据园友韦恩卑鄙的评论,又进行了后续的验证.如果说在前文中,我们还对这是否是个BUG抱着"谨

这是EnterLib PIAB的BUG吗?

在默认的情况下,EnterLib的PIAB采用基于TransparentProxy/RealProxy的机制实现对方法调用的拦截,进而实现了对横切关注点(Crosscutting Concern)的动态注入.也正是其来截机制本身的局限,当我们才用PIAB的方式进行对象的创建的时候,要求本创建对象的类型要么实现某一个接口,要么继承MarshalByRefObject类型.但是当我们让抽象基类继承自MarshalByRefObject就不行了,我个人觉得这是微软需要改进的地方. 一.基于接口实现和对

ItemMouseHover和NodeMouseHover事件不再次触发,在网上找不到答案,感觉是ms的bug

问题描述 问题描述:比如说我的树有两个节点,1和2.当我将鼠标第一次在1上停留时,触发了NodeMouseHover事件.但是当我将鼠标移开(不要在2上触发事件)到一个没有节点的地方,然后再次将鼠标移动到1上停留时,不触发这个事件了.在其他节点可以触发这个事件.也就是说在同一个节点上不能连续两次触发这个事件.这是为什么?怎么解决?自己写timer比较麻烦.有别的办法吗? 解决方案 解决方案二:up解决方案三:在MouseHover楼主想做什么?不过你可以在适当的时候调用this.ResetMou