连续连接数据库时出错

时间:2015-04-24 06:32:40

标签: c# sql azure azure-sql-database

当我在连续循环中查询数据库时,经过一段时间 我收到一个错误:

  

可能由于瞬态而引发异常   失败。如果要连接到SQL Azure数据库,请考虑使用SqlAzureExecutionStrategy。

通常它工作正常。

12 个答案:

答案 0 :(得分:16)

连接到SQL数据库时,您必须考虑瞬时连接失败。例如,当推出更新,硬件失败等时,可能会发生这些连接失败。您看到的错误表明发生了这些事情之一,这是您断开连接的方式。按照Anbuj的建议启用执行策略应解决问题。

答案 1 :(得分:9)

如果您正在使用EF Core配置重试失败以进行弹性连接:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder.UseSqlServer("your_connection_string", builder =>
        {
            builder.EnableRetryOnFailure(5, TimeSpan.FromSeconds(10), null);
        });
    base.OnConfiguring(optionsBuilder);
}

答案 2 :(得分:8)

启用此处提及的执行策略:https://msdn.microsoft.com/en-us/data/dn456835.aspx。在设计Azure SQL DB时,必须设计瞬态连接故障,因为后端更新,硬件故障,负载平衡有时会导致间歇性故障。

答案 3 :(得分:2)

当我尝试连接到数据库的登录时,我在数据库中没有关联用户时出现此错误。

答案 4 :(得分:1)

我正在发布此答案,因为我在研究问题的答案时面临很多问题。以下是我收到的详细错误消息:

将零件中的错误划分为错误时间过长:

  
      
  1. System.Data.Entity.Core.EntityException: *引发了一个异常,该异常很可能是由于瞬时故障引起的。如果你是   连接到SQL Azure数据库时请考虑使用   SqlAzureExecutionStrategy。 * --->

  2.   
  3. 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,动作为1 wrapCloseInAction)

  4.   

经过研究,我发现它与Azure SQL数据库最大登录数的限制有关。我使用的是“ 基本”服务轮胎,最多可同时登录30个用户。

Azure的定价层在性能上有很大的不同。为此,他们限制了许多性能指标,例如CPU功率,每分钟请求数等。

这意味着,如果您要遍历您的层,则请求将开始排队,因为CPU功率/请求量太高而无法处理。这导致超时,然后随着请求等待处理,请求限制增加。最终,它到达了数据库实质上崩溃的地步。

我的经验是,较低的数据库级别(例如S0和S1)的功能不足,除开发或非常基本的站点外,不应将其用于其他任何用途。

Azure门户中有一些很棒的工具,可让您调试数据库中发生的事情,例如CPU图,索引顾问和查询性能见解。

以下是相关链接:

结论:

谢谢。

答案 5 :(得分:1)

我看到没有人将解决方案放在Entity Framework而非EF core的情况下。 实现SqlAzureExecutionStrategy的最简单方法是:

  1. 转到包含以下内容的Context.cs文件:public partial class YourEntity : DbContext

  2. 添加引用:using System.Data.Entity.SqlServer;

  3. 在包含以下内容的文件末尾添加另一个类 代码:

    public MyConfiguration()
    {
        SetExecutionStrategy("System.Data.SqlClient", () => new SqlAzureExecutionStrategy());
        SetDefaultConnectionFactory(new LocalDbConnectionFactory("mssqllocaldb"));
    }
    

有关更多信息,您可以参考this documentation

答案 6 :(得分:1)

在我的例子中,这个错误是由于缺少 await 在查询执行过程中处理上下文造成的。

答案 7 :(得分:0)

如果您的数据库是本地的,让我们说一个WebAPI,有时您必须提供数据源= localhost而不是IP地址。 我们遇到的情况是我们使用一些VPS并且没有将数据源设置为localhost会出现此错误。 所以,如果有其他人经历过这个,那可能对他有帮助。

答案 8 :(得分:0)

这可能是因为TLS设置,.net 4.5框架默认不支持tls 1.2,新的SQL db与旧的tls ver不兼容。  所以要么在你的机器上禁用tls 1.0,1.1,要么更新到.net 4.6.2

答案 9 :(得分:0)

此问题的解决方案是通过建议的答案,使用SetExecutionStrategy()打开重试策略。另外,请确保派生自类DbConfiguration,以便Entity Framework可以自动执行该方法。

您还希望通过设置会产生连接错误的命令拦截来确保连接弹性确实起作用,以便您可以确认它是否起作用。

More about how to handle transient connection errors

答案 10 :(得分:0)

我想为那些像我一样遇到此错误的人做出贡献,即使他们不必与Azure或云中另一个平台上的数据库进行交互。

首要目标是找到问题的确切原因;像我一样,许多人会与异常文本和一英里长的堆栈跟踪字符串发生冲突。对于我来说,处理InnerExceptions的matryoshkas很有用,以便在关闭连接之前(该消息处于活动状态!)获得数据库提供程序发出的真实消息。或者,如果可能的话,从一个外部工具监视到数据库的事务就足够了,该外部工具使您可以检查与正在进行的TSQL操作有关的任何错误(例如SQL Server Profiler)。

在我的情况下,情况是这样的:同一程序(它是Windows服务)的2个实例在表中插入记录。两种特点:

  • 对于Windows服务,例如Form或WPF桌面应用程序,DbContext的生命周期通常更长,并且可以将其链接到正在处理的Form上,而不是在具有有远见的定期刷新它以清除当时为止的值的缓存;
  • 目标表具有其自己的自动增量(整数)键字段

在这种情况下,同时,所有服务的实例都尝试写入同一表,并且使用EF6执行的每个写入操作都会生成一个查询,该查询在其中具有非常特殊的选择,用于检索和增强它代表身份的键字段。像这样:

INSERT [dbo].[People]([Name]) VALUES (@0)
SELECT [Id], [SomeId]
FROM [dbo].[People]
WHERE @@ROWCOUNT > 0 AND [Id] = scope_identity()

我的代码是:

People entry = new People();
entry.name = "ABCD";
_ctx.Set<People>().Add(entry);
await _ctx.SaveChangesAsync();

这种类型的书写会导致两个进程之间出现并发情况(尤其是当表具有约5M记录时),这导致SQL引擎解析一个请求并取消另一个请求。调用程序的解释恰好是“ 引发了一个异常,该异常很可能是由于瞬时故障引起的。如果要连接到SQL Azure数据库,请考虑使用SqlAzureExecutionStrategy。”

要解决该问题,我必须放弃分配给新记录的增量ID的恢复,将表视为堆栈,并使用以下方法将写操作减少为直接插入操作:

await _ctx.Database.ExecuteSqlCommandAsync("INSERT INTO ....");

或者,可以使用两个不涉及EF TSQL解析器的写操作来完善操作,还可以检索分配给最后添加的记录的标识符。

答案 11 :(得分:0)

尝试使用 ef core 2.2 获取 sp 结果时出现此错误 然后我尝试在我的 sp 的开头使用此代码,问题解决了。

ALTER procedure [dbo].[getusers]
@param int
As
Set transaction isolation level read uncommitted
.
.

.

相关问题