我的Azure角色grabs stuff to process from a database - 它包含System.Data.SqlClient.SqlConnection
的实例,并定期创建SqlCommand
实例并执行SQL查询。
现在偶尔(通常是几天一次)运行查询会触发SqlException
异常
该服务在处理您的请求时遇到错误。请再试一次。错误代码40143。 当前命令发生严重错误。结果(如果有的话)应该被丢弃。
我已经多次看过,现在我的代码捕获了它,在Dispose()
实例上调用SqlConnection
,然后重新打开连接并重试查询。后者通常导致另一个SqlException
异常
超时已过期。操作完成之前经过的超时时间或服务器没有响应。
这看起来非常像SQL Azure服务器因任何原因无法响应或无法使用。
目前我的代码没有捕获后一个异常,它在RoleEntryPoint.Run()
之外传播,并且角色重新启动。重启通常需要大约十分钟,一旦完成,问题就会消失一天左右。
我不喜欢我的角色重新启动 - 这需要一段时间,我的服务功能受到阻碍。我想做一些更聪明的事。
解决这个问题的策略是什么?我应该多次重试查询多少次以及间隔多少次?我应该做别的吗?我何时放弃并让角色重启?
答案 0 :(得分:14)
我强烈建议您查看Transient Fault Handling Framework for SQL Azure
这将帮助您处理连接和查询尝试的重试逻辑,我在生产中使用它并且它工作得很好。还有一篇很好的文章on technet可能会有所帮助。
[编辑:2013年10月17日]
的模式和实践小组已经看到了这一点答案 1 :(得分:2)
我们使用TransientFaultHandling并且它不会处理所有奇怪的异常。
例如,昨天突然出现了这个:
该服务在处理您的请求时遇到错误。请再试一次。错误代码40143。 当前命令发生严重错误。结果(如果有的话)应该被丢弃。 ,stacktrace at System.Data.SqlClient.SqlConnection.OnError(SqlException exception,Boolean breakConnection) 在System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() 在System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior,SqlCommand cmdHandler,...
即使这样也能合理的合理方法:
典型工作流程示例:
在试一试中将B一起包裹在C中。如果在“无害”期间发生了某些事情。 SQL Azure调用,只需在不删除消息的情况下进行挽救,它将在可见性超时到期后再次弹出。
实际上,这是非常常见的方法:组织成类似事务的块,将块包装到try-catch中,整齐地回滚异常。永远不要假设某些电话不会失败。所有呼叫都会不时失败。