猿问

没有任何 SELECT(!):“已经有一个与此连接关联的打开的 DataReader”

我知道“已经有一个与此连接相关联的打开的 DataReader”(编辑:最初编写的“命令”)存在类似的问题 - 但在所有情况下都涉及一些 SELECT 命令。

我的情况不同:在这台机器上,没有执行 SELECT 命令(它们在不同的物理计算机上),只有 INSERT 和 UPDATE 命令。

怎么会这样?acommand.ExecuteNonQuery()或 a是否command.Prepare()仍然打开 DataReader?那将是一个WTF,但至少是一个解释。


慕容708150
浏览 307回答 2
2回答

蛊毒传说

查看了SqlCommand和的参考源后OleDbCommand,它们的ExecuteNonQuery方法实现中都有一些快速路径,这些路径将尝试避免打开数据读取器,但都有一条慢速路径,将回退到使用数据读取器(显然,数据读取器路径必须应对所有可能的选择,并且他们不想重复所有这些代码,并非不合理)。我怀疑您用来连接的任何选项1mysql将有类似的实现。所以,首先也是最重要的,它不一定是SELECT引起冲突的。不过,修复应该很简单,并且是很好的一般建议。不要共享任何数据库对象。当然,您的连接字符串只有一个来源,但一般来说,如果您需要一个连接对象,new则将其放在那里,然后在using语句中使用它。命令对象也是如此。对于读者,您不会new自己修改它们,但您仍然需要using.如果您不重用数据库对象,则永远不会出现此错误。唯一的例外(在我的书中)是如果您使用客户端控制的事务(例如TransactionScope或类似的),您确实希望共享连接对象。但是您仍然不需要共享命令对象。如果事务如此广泛,以至于您无法跟踪(可能已经)在其上执行的所有命令,我建议它太大了。1上次我看有几个竞争者mysql可以使用IDbConnectionet al 层次结构、plusOleDbCommand和 family 的特定实现。

呼如林

根据 Bradley Grainger 的评论(MySqlConnection 的线程安全问题),我可以通过确保没有并行运行查询来解决这个问题。这意味着原始异常消息可能是错误的(不能排除 Damien_The_Unbeliever 的回答中提到的一些奇怪的路径)。
随时随地看视频慕课网APP
我要回答