在 Azure 数据库中使用 OWIN 访问“错误:19 - 物理连接不可用”

Posted

技术标签:

【中文标题】在 Azure 数据库中使用 OWIN 访问“错误:19 - 物理连接不可用”【英文标题】:“error: 19 - Physical connection is not usable” with OWIN access in Azure database 【发布时间】:2014-05-19 11:10:19 【问题描述】:

我已经尝试了关于可怕的“错误 19”的所有其他帖子,发现少数有答案的帖子不适用或没有帮助,因此发布了这篇新帖子。对于所有 Azure+EF 用户来说,这是一个非常严重的潜在问题。

第一次出现:

我正在使用 VS2013 EF6.1 Razor 项目中所有内容的最新版本(最后列出的包)。该数据库托管在 SQL Azure 上。

在运行我的 webapp 几次后(在开发环境中)我收到此错误:A transport-level error has occurred when receiving results from the server. (provider: Session Provider, error: 19 - Physical connection is not usable)

它死掉的那一行总是这样:

我收集到错误与连接池(以及连接不足)有关,但我无法在任何地方发现泄漏。

当我在整个应用程序中访问 OWIN 成员资格和其他数据库功能时,我有一个 DatabaseContoller,所有其他控制器都从该 DatabaseContoller 继承。这将创建所有相关组件并处理它们。

数据库控制器.cs

[Authorize]
public class DatabaseController : Controller

    #region properties
    /// <summary>
    /// User manager - attached to application DB context
    /// </summary>
    protected UserManager<ApplicationUser> UserManager  get; set; 

    /// <summary>
    /// Role manager - attached to application DB context
    /// </summary>
    protected RoleManager<IdentityRole> RoleManager  get; set; 

    /// <summary>
    /// Application DB context
    /// </summary>
    protected ApplicationDbContext ApplicationDbContext  get; set; 

    /// <summary>
    /// Database context used by most controllers
    /// </summary>
    protected ApplicationEntities Context  get; set; 
    #endregion properties

    #region Constructors
    public DatabaseController()
    
        this.Context = new ApplicationEntities ();
        this.ApplicationDbContext = new ApplicationDbContext();
        this.UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(this.ApplicationDbContext));
        this.RoleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(this.ApplicationDbContext));
        this.UserManager.UserValidator = new UserValidator<ApplicationUser>(UserManager)  AllowOnlyAlphanumericUserNames = false ;
    
    #endregion Constructors

    protected override void Dispose(bool disposing)
    
        if (disposing)
        
            if (UserManager != null)
            
                this.UserManager.Dispose();
                this.UserManager = null;
            
            if (this.RoleManager != null)
            
                this.RoleManager.Dispose();
                this.RoleManager = null;
            
            if (this.ApplicationDbContext != null)
            
                this.ApplicationDbContext.Dispose();
                this.ApplicationDbContext = null;
            
            if (this.Context != null)
            
                this.Context.Dispose();
                this.Context = null;
            
        
        base.Dispose(disposing);
    

已安装的软件包

  <package id="Antlr" version="3.5.0.2" targetFramework="net45" />
  <package id="bootstrap" version="3.1.1" targetFramework="net45" />
  <package id="EntityFramework" version="6.1.0" targetFramework="net45" />
  <package id="jQuery" version="1.11.0" targetFramework="net45" />
  <package id="jQuery.Validation" version="1.11.1" targetFramework="net45" />
  <package id="json2" version="1.0.2" targetFramework="net45" />
  <package id="Microsoft.AspNet.Identity.Core" version="2.0.0" targetFramework="net45" />
  <package id="Microsoft.AspNet.Identity.EntityFramework" version="2.0.0" targetFramework="net45" />
  <package id="Microsoft.AspNet.Identity.Owin" version="2.0.0" targetFramework="net45" />
  <package id="Microsoft.AspNet.Mvc" version="5.1.1" targetFramework="net45" />
  <package id="Microsoft.AspNet.Razor" version="3.1.2" targetFramework="net45" />
  <package id="Microsoft.AspNet.Web.Optimization" version="1.1.3" targetFramework="net45" />
  <package id="Microsoft.AspNet.WebApi" version="5.1.2" targetFramework="net45" />
  <package id="Microsoft.AspNet.WebApi.Client" version="5.1.2" targetFramework="net45" />
  <package id="Microsoft.AspNet.WebApi.Core" version="5.1.2" targetFramework="net45" />
  <package id="Microsoft.AspNet.WebApi.WebHost" version="5.1.2" targetFramework="net45" />
  <package id="Microsoft.AspNet.WebPages" version="3.1.2" targetFramework="net45" />
  <package id="Microsoft.jQuery.Unobtrusive.Validation" version="3.1.2" targetFramework="net45" />
  <package id="Microsoft.Owin" version="2.1.0" targetFramework="net45" />
  <package id="Microsoft.Owin.Host.SystemWeb" version="2.1.0" targetFramework="net45" />
  <package id="Microsoft.Owin.Security" version="2.1.0" targetFramework="net45" />
  <package id="Microsoft.Owin.Security.Cookies" version="2.1.0" targetFramework="net45" />
  <package id="Microsoft.Owin.Security.Facebook" version="2.1.0" targetFramework="net45" />
  <package id="Microsoft.Owin.Security.Google" version="2.1.0" targetFramework="net45" />
  <package id="Microsoft.Owin.Security.MicrosoftAccount" version="2.1.0" targetFramework="net45" />
  <package id="Microsoft.Owin.Security.OAuth" version="2.1.0" targetFramework="net45" />
  <package id="Microsoft.Owin.Security.Twitter" version="2.1.0" targetFramework="net45" />
  <package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net45" />
  <package id="Modernizr" version="2.7.2" targetFramework="net45" />
  <package id="Newtonsoft.Json" version="6.0.2" targetFramework="net45" />
  <package id="Owin" version="1.0" targetFramework="net45" />
  <package id="Owin.Security.Providers" version="1.3.1" targetFramework="net45" />
  <package id="Respond" version="1.4.2" targetFramework="net45" />
  <package id="WebGrease" version="1.6.0" targetFramework="net45" />

假设是连接泄漏,我该如何追踪泄漏源?

如果您需要更多信息,请尽管询问。

更新:2014 年 5 月 22 日提供第二次赏金

我仍然遇到同样的问题,自上次发布以来对项目进行了一些细微的更改,因此将在下面发布最新的详细信息。

我已将Connection Lifetime=3;Max Pool Size=3; 添加到我的连接字符串中,基于this post。

更新:2014 年 5 月 23 日错误仍然出现

第二天,调试了几十次,这个错误又回来了。

更新:2014 年 6 月 11 日

经过 2 次赏金和无数 Google 调查(对此没有真正的答案),我不得不假设这是 Entity Framework 6 中的一个缺陷,是我以某种方式导致出现的。

更多信息:

我刚刚在 WinForm 项目中遇到了同样的错误,请连接到 Azure。在这种情况下,我不小心在每添加 20 个新项目后没有清除实体列表。

每次运行代码时,它都会增加 20 条记录,并更新所有记录的 DateModified 字段。当它达到 1700 条正在更新的记录时,它突然给出了可怕的“错误 19 - 物理连接不可用”。之后,我需要重新启动调试 IIS 才能使其正常工作。

显然代码已经运行了大量更新,也许这会帮助某人想到某事

【问题讨论】:

也许你没有打电话给Close?检查这个:wishmesh.com/2013/10/… @DiegoG:关闭 which EF 或 OWIN 对象?他们中的任何一个人都结束了吗? 也许它有助于在处置过程中运行System.GC.Collect()(我知道这很糟糕)以查找它是否是 EF 泄漏? 虽然Dispose()应该关闭连接不管GC,也许你可以尝试使用显式this.Context.Connection.Close() 这东西太可怕了。我有同样的问题:Azure + EF6,即使是SqlAzureExecutionStrategy。我还没有正确处理我的 DbContexts,所以我现在尝试一下。如果这为我解决了问题,我会告诉你... 【参考方案1】:

您是否尝试过 SqlAzureExecutionStrategy?听起来连接被切断了,但使用此策略 EF 应该会自动重试重新连接。

http://msdn.microsoft.com/en-us/data/dn456835.aspx

【讨论】:

我一定会调查的。此错误的主要特点是一旦发生(至少在本地),您需要重新启动 IIS 实例以避免再次立即发生。这意味着重试将无济于事,但此时任何事情都值得尝试。感谢您的信息:) 我也有类似的问题,我可以确认使用 SqlAzureExecutionStrategy 是要走的路。必须使用重试策略访问 Azure 上的任何资源。 默认 SqlExecutionStrategy 不处理此错误(在最新的 EF 6.1.3 上检查)。仅处理以下错误编号:40613,41301,41302,41305,41325,10928,10929,40197,40501,233,10053,10054,10060,20,64(请参阅 EntityFramework.SqlServer 程序集中的 SqlAzureRetriableExceptionDetector 类)。 但是,您可以使用自己的执行策略,按照 here 的建议处理此错误。 刚刚再次确认,如果您稍后在引用相关表的属性时缺少.Include(x=&gt;x.ForegnTable),则会收到此错误。延迟评估似乎在某些查询上失败。它实际上根本不是通讯错误,我们没有发现更改 SqlAzureExecutionStrategy 有任何效果。【参考方案2】:

错误 19 不是通讯错误! (或者不仅仅是通讯错误)

只需确保您的 LINQ to SQL 查询中有所有必需的 .Include(x=&gt;x.ForeignTable) 调用!

2015 年 8 月更新(可能的解决方案,至少,某些场景):

我们刚刚有一个关于这个问题的 100% 重现案例,我们能够通过反复试验来解决,所以它很可能是一个解决方案,或者至少提供了寻找什么的线索。

场景:

该错误仅发生在 IIS 下运行的发布版本下。它没有在调试或 IIS Express 下发生。 我们还开启了 SQL 分析,以查看服务器实际受到攻击的时间/地点。 有问题的查询正在获取匹配的记录,然后在结果的foreach 迭代中创建视图模型(即惰性评估)。视图模型依赖于查询实体的相关表中的值。

测试:

第一次尝试:删除查询中的所有复杂过滤器

结果:仍然失败,出现错误 19

第二次尝试:将ToList() 添加到查询中以强制查询立即运行完成

结果:成功!!! (显然这里发生了一些事情)

第三次尝试:删除ToList()并将.Include(x=&gt;x.ForeignTable)添加到查询中以强制包含相关数据。

结果: 成功

我的新理论是:

如果你不小心遗漏了外部表的Include,EF 在延迟评估时将随机无法获取相关数据。这会导致臭名昭著的错误 19。

由于Identify Framework 中存在外键关系,您可能会假设在OWIN 中某处的查询中也缺少.Include() 或等效项。在使用 OWIN 或其他查询时,这可能会导致随机问题。

注意事项:

要带走的关键点是错误 19 不是通信错误。查询确实命中 SQL 服务器。这是客户端无法获取相关数据的问题。

暂停掌声(我们很高兴找到这个) :)

2015 年 8 月 28 日更新:

今天再次遇到可怕的错误 19,连接到本地 SQL 数据库(通常这对我来说是 Azure 的问题)。根据上面的结果,我只是在适当的地方添加了一个.Include(x=&gt;x.ForeignTable) 语句,问题就消失了!这似乎是 EF 并不总是能够延迟加载相关表信息的问题。

【讨论】:

以上是关于在 Azure 数据库中使用 OWIN 访问“错误:19 - 物理连接不可用”的主要内容,如果未能解决你的问题,请参考以下文章

Azure OpenID Connect 通过 OWIN 中间件导致无限重定向循环

openid connect owin 如何验证来自 Azure AD 的令牌?

如何将 Azure OpenIdConnect OWIN 中间件 Cookie Auth 转换为 SPA 应用程序的 JavaScript JWT?

使用 OWIN 在 ASP.NET MVC 5 应用程序中存储和检索 facebook 访问令牌

Azure 功能:访问存储帐户时出现 403 错误

OWIN / Katana 的未处理异常全局处理程序?