我有一个这样的开放SqlConnection
代码:
using (var transaction = connection.BeginTransaction()) {
using (var command = connection.CreateCommand()) {
command.Transaction = transaction;
command.CommandText = "MyQueryText";
using( var reader = command.ExecuteReader() ) {
//read data
}
}
}
我一直在经历一些“不可能的代码”症状并订阅了SqlConnection.StateChange
事件,现在我发现在某些时候使用以下堆栈调用事件(状态正在从更改Open
为Closed
):
at MyHandler.onStateChange(Object sender, StateChangeEventArgs e)
at System.Data.ProviderBase.DbConnectionInternal.CloseConnection(DbConnection owningObject, DbConnectionFactory connectionFactory)
at System.Data.SqlClient.SqlConnection.Close()
at System.Data.SqlClient.SqlInternalConnectionTds.BreakConnection()
at System.Data.SqlClient.TdsParserStateObject.ReadSniError(TdsParserStateObject stateObj, UInt32 error)
at System.Data.SqlClient.TdsParserStateObject.ReadSni(DbAsyncResult asyncResult, TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParserStateObject.ReadNetworkPacket()
at System.Data.SqlClient.TdsParserStateObject.ReadByte()
at System.Data.SqlClient.SqlDataReader.SetMetaData(_SqlMetaDataSet metaData, Boolean moreInfo)
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
at System.Data.SqlClient.SqlDataReader.ConsumeMetaData()
at System.Data.SqlClient.SqlDataReader.get_MetaData()
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
at System.Data.SqlClient.SqlCommand.ExecuteReader()
// my code calling `ExecuteReader()`
所以运行时遇到一些随机错误(我猜是网络连接问题)并关闭连接,然后将关闭的阅读器对象返回给我的代码,并尝试使用返回的阅读器 yield InvalidOperationException
。
我需要以某种方式解决它。显然会发生随机网络错误。我的代码中有重试逻辑,可以处理SqlException
网络问题引发的 s,但在这里我面对的是一个封闭的阅读器,然后是一个InvalidOperationException
.
我的第一个想法是编写自己的ExecuteReader()
调用 native 的方法ExecuteReader()
,检查是否返回了已关闭的阅读器,如果发生这种情况,则抛出一个新的ClosedReaderReturnedException
,我还将更改重试代码,以便它也对此类异常做出反应并重新运行查询。
我的解决方案好吗?有更好的解决方案吗?