use*_*324 37 c# sql azure azure-sql-database
当我在连续循环中从数据库查询时,一段时间后我收到一个错误:
引发的异常可能是由于瞬态故障引起的.如果要连接到SQL Azure数据库,请考虑使用SqlAzureExecutionStrategy.
通常它工作正常.
小智 15
连接到SQL数据库时,必须考虑瞬时连接故障.例如,当推出更新,硬件失败等时,可能会发生这些连接失败.您看到的错误表明发生了这些事情之一,这是您断开连接的方式.按照Anbuj的建议启用执行策略应该可以解决问题.
She*_*har 13
如果您使用EF Core配置重试失败以进行弹性连接:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("your_connection_string", builder =>
{
builder.EnableRetryOnFailure(5, TimeSpan.FromSeconds(10), null);
});
base.OnConfiguring(optionsBuilder);
}
Run Code Online (Sandbox Code Playgroud)
启用此处提到的执行策略:https://msdn.microsoft.com/en-us/data/dn456835.aspx.在设计Azure SQL DB时,必须设计瞬态连接故障,因为后端更新,硬件故障,负载平衡有时会导致间歇性故障.
我可以看到没有人将解决方案放在实体框架而不是 EF core 的情况下。实现 SqlAzureExecutionStrategy 最简单的方法是:
转到包含以下内容的 Context.cs 文件:public partial class YourEntity : DbContext
添加参考:using System.Data.Entity.SqlServer;
在文件末尾添加另一个包含以下代码的类:
public MyConfiguration()
{
SetExecutionStrategy("System.Data.SqlClient", () => new SqlAzureExecutionStrategy());
SetDefaultConnectionFactory(new LocalDbConnectionFactory("mssqllocaldb"));
}
Run Code Online (Sandbox Code Playgroud)您可以参考此文档以获取更多信息。
小智 6
我想为那些像我一样遇到此错误的人做出贡献,即使他们没有处于必须与 Azure 或云中其他平台上的数据库进行交互的情况。
第一个目标是找到问题的确切根源;像我一样,许多人都会与异常文本和一英里长的堆栈跟踪字符串发生冲突。对我来说,处理 InnerExceptions 的 matryoshka 以获得数据库提供程序在关闭连接之前发出的真实消息(该消息在消息发生时处于活动状态!)非常有用。或者,如果可能的话,从外部工具监控数据库事务就足够了,该工具允许您检查与正在进行的 TSQL 操作相关的任何错误(例如 SQL Server Profiler)。
在我的例子中,场景是这样的:同一个程序(它是一个 Windows 服务)的 2 个实例在表中插入记录。两个特点:
在这种情况下,所有服务的实例同时尝试写入同一个表,并且使用 EF6 执行的每个写入操作都会生成一个查询,其中包含一个非常特定的选择,用于检索和增强它代表身份的关键字段。像这样的东西:
INSERT [dbo].[People]([Name]) VALUES (@0)
SELECT [Id], [SomeId]
FROM [dbo].[People]
WHERE @@ROWCOUNT > 0 AND [Id] = scope_identity()
Run Code Online (Sandbox Code Playgroud)
我的代码是:
People entry = new People();
entry.name = "ABCD";
_ctx.Set<People>().Add(entry);
await _ctx.SaveChangesAsync();
Run Code Online (Sandbox Code Playgroud)
这种写法会导致两个进程之间出现并发的情况(特别是当表有大约5M条记录时),这会导致SQL引擎解析一个请求并取消另一个请求。调用程序的解释正是“发生了异常,可能是由于暂时性故障。如果您要连接到 SQL Azure 数据库,请考虑使用 SqlAzureExecutionStrategy。 ”
为了解决这个问题,我不得不放弃恢复分配给新记录的增量 id,将表视为堆栈,并使用以下方法将写入操作减少为直接插入操作:
await _ctx.Database.ExecuteSqlCommandAsync("INSERT INTO ....");
Run Code Online (Sandbox Code Playgroud)
或者,可以使用两个不涉及 EF TSQL 解析器的写入操作来优化操作,并且还可以检索分配给最后添加的记录的标识符。
我发布这个答案是因为我在研究问题答案时遇到很多问题。以下是我收到的详细错误消息:
由于错误太长,将错误分为几个部分:
System.Data.Entity.Core.EntityException:*已引发异常,可能是由于暂时性故障所致。如果要连接到 SQL Azure 数据库,请考虑使用 SqlAzureExecutionStrategy。* --->
System.Data.Entity.Core.EntityCommandExecutionException:执行命令定义时发生错误。有关详细信息,请参阅内部异常。---> System.Data.SqlClient.SqlException:资源 ID: 1。数据库的请求限制为 30,已达到。请参阅“ http://go.microsoft.com/fwlink/?LinkId=267637 ”以获取帮助。在System.Data.SqlClient.SqlConnection.OnError(SqlException异常,布尔breakConnection,Action`1wrappCloseInAction)
经过研究发现,这与Azure SQL数据库最大登录数限制有关。我使用的是“基本”服务轮胎,可以登录的最大并发用户数为 30。
Azure 的定价层在性能方面存在显着差异。为了实现这一目标,他们限制了许多性能指标,例如 CPU 功率、每分钟请求数等。
这意味着,如果您超出层级,您的请求将开始排队,因为 CPU 功率/请求量太高而无法处理。这会导致超时,然后随着请求等待处理,请求限制会增加。最终,它达到了数据库基本上崩溃的地步。
我的经验是,较低的数据库级别(例如 S0 和 S1)功能不足,不应该用于开发或非常基本的站点以外的任何用途。
Azure 门户中有一些很棒的工具可让您调试数据库的运行情况,例如 CPU 图表、索引顾问和查询性能洞察。
以下是相关链接:
结论:
第 1 部分:启用此处提到的执行策略: https://msdn.microsoft.com/en-us/data/dn456835.aspx。
第2部分:您需要升级Azure中的订阅(如果价格允许)。
谢谢。