我想为我的数据库调用(使用C#和用于访问数据库的Microsoft技术)编写一些包装器代码,并在“瞬态”异常时自动重试。暂时的,我的意思是说,很有可能最终解决(相对于永远不会起作用的逻辑错误)。我能想到的例子包括:
我曾计划使用SqlException的错误号来发现这些错误。因此,例如:
List<RunStoredProcedureResultType> resultSet = null;
int limit = 3;
for (int i = 0; i < limit; ++i)
{
bool isLast = i == limit - 1;
try
{
using (var db = /* ... */)
{
resultSet = db.RunStoredProcedure(param1, param2).ToList();
}
//if it gets here it was successful
break;
}
catch (SqlException ex)
{
if (isLast)
{
//3 transient errors in a row. So just kill it
throw;
}
switch (ex.Number)
{
case 1205: //deadlock
case -2: //timeout (command timeout?)
case 11: //timeout (connection timeout?)
// do nothing - continue the loop
break;
default:
//a non-transient error. Just throw the exception on
throw;
}
}
Thread.Sleep(TimeSpan.FromSeconds(1)); //some kind of delay - might not use Sleep
}
return resultSet;
(对我来说,如果有任何错误,请原谅,我只是即时编写的。我也意识到我可以很好地将其包装起来...)
因此,关键问题是:我应该将哪些数字视为“瞬态”(我意识到我认为瞬态的数字可能与其他人认为瞬态的数字不同)。我在这里找到了一个不错的清单:
https://msdn.microsoft.com/zh-CN/library/cc645603.aspx
但是它的庞大和注释非常有用。是否还有其他人建立了他们用于类似目的的列表?
更新
最后,如果错误是已知的“非暂时性错误”列表中的一个,则我们选择了“错误列表”,通常是程序员错误。我列出了我们用作答案的数字列表。
很抱歉回答我自己的问题,但是如果仍然有人感兴趣,我们就开始建立自己的错误代码列表。这并不理想,但是我们认为这不应该经常发生。
我们选择了“不良清单”方法,而不是问题中暗示的“良好清单”方法。到目前为止,我们拥有的ID是:
PARAMETER_NOT_SUPPLIED = 201;
CANNOT_INSERT_NULL_INTO_NON_NULL = 515;
FOREGIN_KEY_VIOLATION = 547;
PRIMARY_KEY_VIOLATION = 2627;
MEMORY_ALLOCATION_FAILED = 4846;
ERROR_CONVERTING_NUMERIC_TO_DECIMAL = 8114;
TOO_MANY_ARGUMENTS = 8144;
ARGUMENT_IS_NOT_A_PARAMETER = 8145;
ARGS_SUPPLIED_FOR_PROCEDURE_WITHOUT_PARAMETERS = 8146;
STRING_OR_BINARY_TRUNCATED = 8152;
INVALID_POINTER = 10006;
WRONG_NUMBER_OF_PARAMETERS = 18751;
我们注意到的另一件事是,如果连接池超时,则不会收到SqlException-而是会收到一个InvalidOperationException报告“超时已过期”。遗憾的是它不是SqlException,但值得一试。
我会尽量保持最新状态,并增加任何内容。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句