"There is already an open DataReader associated with this Command which must be closed first"错误...

本文探讨了使用LINQ时出现的特定异常:“ThereisalreadyanopenDataReaderassociatedwiththisCommandwhichmustbeclosedfirst”。文章分析了异常产生的原因,并提供了两种解决方案:一是调整存储过程设计避免返回结果集;二是修改连接字符串启用“MultipleActiveResultSets=True”。同时介绍了如何解除表锁定状态。

其实这个错误跟LINQ To Sql没有必然的关系, 不过我觉得见到它的场景一般情况下都应该是用LINQ的时候.

以下示例代码:

 1            try
 2ExpandedBlockStart.gifContractedBlock.gif            {
 3                dc.SubmitChanges();
 4                dc.sp1();
 5                tran.Commit();
 6            }

 7            catch (Exception ex)
 8ExpandedBlockStart.gifContractedBlock.gif            {
 9                tran.Rollback();
10                Master.SetError(ex.Message);
11                return;
12            }

如果在try块的前面dc上有select 动作, 并且存储过程sp1 中也有select动作, 则上述语句将抛出异常:
There is already an open DataReader associated with this Command which must be closed first

经过单步跟踪, 第一次是tran.Commit 先抛出异常, 被catch块捕捉, 执行tran.Rollback时再次抛出异常, 这里没有捕捉器了,整个程序于是异常. 如果仅仅是异常还算好事了, 由于LINQ 事务操作的时候, 是用排它锁锁定目标表的, 所以事务没有结束, 目标表就一直被锁定, 这里由于事务既无法提交也无法回滚, 所以目标表被锁死.

看得出这个错误是毁灭性的.
究其原因, 是因为默认情况下, 不允许返回多个dataSet, 如果不用LINQ的话, 我想基本上也不会需要返回多个dataset, 所以应该很少会碰到这个错误, 但是用linq的话,概率就很大了. 解决办法:
1. 不要在存储过程中返回结果集.(貌似不太现实...)
2. 给连接字符串加上"MultipleActiveResultSets=True"

如果表已经被锁死, 解决办法:
1. 重启SQL SERVER 服务
2. 先在查询分析器上按ctrl+2 , 返回当前锁定的情况. 例如:

spid dbid ObjId IndId Type Resource Mode Status
51   5      0      0       DB                   X      GRANT

找到Mode 带"X"的项的spid, 例如上面一行, spid是51, 在查询分析器中执行: KILL 51

 

感觉不可理解的是为什么事务回滚也会抛出异常, 使得这个错误一旦发生后果就极其严重, 无论是何种初衷禁止返回多个结果集, 都不应该让表这样被锁死, 鄙视一下微软...

转载于:https://www.cnblogs.com/Moosdau/archive/2009/03/23/1419575.html

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值