博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Is this a MS EnterLib DAAB BUG or not?
阅读量:5877 次
发布时间:2019-06-19

本文共 2365 字,大约阅读时间需要 7 分钟。

开门见山,使用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
微博:
如果你想及时得到个人撰写文章以及著作的消息推送,或者想看看个人推荐的技术资料,可以扫描左边二维码(或者长按识别二维码)关注个人公众号(原来公众帐号
蒋金楠的自媒体将会停用)。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
你可能感兴趣的文章
那些年追过的......写过的技术博客
查看>>
小米手机解锁bootload教程及常见问题
查看>>
Python内置函数property()使用实例
查看>>
Spring MVC NoClassDefFoundError 问题的解决方法。
查看>>
CentOS 6.9配置网卡IP/网关/DNS命令详细介绍及一些常用网络配置命令(转)
查看>>
python基础教程_学习笔记19:标准库:一些最爱——集合、堆和双端队列
查看>>
C# 解决窗体闪烁
查看>>
CSS魔法堂:Transition就这么好玩
查看>>
【OpenStack】network相关知识学习
查看>>
centos 7下独立的python 2.7环境安装
查看>>
[日常] 算法-单链表的创建
查看>>
前端工程化系列[01]-Bower包管理工具的使用
查看>>
使用 maven 自动将源码打包并发布
查看>>
Spark:求出分组内的TopN
查看>>
Python爬取豆瓣《复仇者联盟3》评论并生成乖萌的格鲁特
查看>>
关于跨DB增量(增、改)同步两张表的数据小技巧
查看>>
飞秋无法显示局域网好友
查看>>
学员会诊之03:你那惨不忍睹的三层架构
查看>>
vue-04-组件
查看>>
Golang协程与通道整理
查看>>