zoukankan      html  css  js  c++  java
  • Is this a MS EnterLib DAAB BUG or not?

    开门见山,使用MS Enterprise LibraryDAABData 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:  

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


    作者:Artech
    出处:http://artech.cnblogs.com
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    channels的使用
    paramiko模块(远程操作服务器)
    GIT版本管理工具教程
    Python中的魔术方法详解(双下方法)
    Django中Q查询及Q()对象
    Python3操作Excel
    漏洞复现环境集锦-Vulhub
    CVE-2019-0193 远程命令执行-漏洞复现
    Weblogic-SSRF 漏洞复现
    CVE-2020-0796 永恒之蓝?
  • 原文地址:https://www.cnblogs.com/artech/p/1441394.html
Copyright © 2011-2022 走看看