在 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=>x.ForegnTable)
,则会收到此错误。延迟评估似乎在某些查询上失败。它实际上根本不是通讯错误,我们没有发现更改 SqlAzureExecutionStrategy
有任何效果。【参考方案2】:
错误 19 不是通讯错误! (或者不仅仅是通讯错误)
只需确保您的 LINQ to SQL 查询中有所有必需的 .Include(x=>x.ForeignTable)
调用!
2015 年 8 月更新(可能的解决方案,至少,某些场景):
我们刚刚有一个关于这个问题的 100% 重现案例,我们能够通过反复试验来解决,所以它很可能是一个解决方案,或者至少提供了寻找什么的线索。
场景:
该错误仅发生在 IIS 下运行的发布版本下。它没有在调试或 IIS Express 下发生。 我们还开启了 SQL 分析,以查看服务器实际受到攻击的时间/地点。 有问题的查询正在获取匹配的记录,然后在结果的foreach
迭代中创建视图模型(即惰性评估)。视图模型依赖于查询实体的相关表中的值。
测试:
第一次尝试:删除查询中的所有复杂过滤器
结果:仍然失败,出现错误 19第二次尝试:将ToList()
添加到查询中以强制查询立即运行完成。
第三次尝试:删除ToList()
并将.Include(x=>x.ForeignTable)
添加到查询中以强制包含相关数据。
我的新理论是:
如果你不小心遗漏了外部表的Include
,EF 在延迟评估时将随机无法获取相关数据。这会导致臭名昭著的错误 19。
由于Identify Framework 中存在外键关系,您可能会假设在OWIN 中某处的查询中也缺少.Include()
或等效项。在使用 OWIN 或其他查询时,这可能会导致随机问题。
注意事项:
要带走的关键点是错误 19 不是通信错误。查询确实命中 SQL 服务器。这是客户端无法获取相关数据的问题。暂停掌声(我们很高兴找到这个) :)
2015 年 8 月 28 日更新:
今天再次遇到可怕的错误 19,连接到本地 SQL 数据库(通常这对我来说是 Azure 的问题)。根据上面的结果,我只是在适当的地方添加了一个.Include(x=>x.ForeignTable)
语句,问题就消失了!这似乎是 EF 并不总是能够延迟加载相关表信息的问题。
【讨论】:
以上是关于在 Azure 数据库中使用 OWIN 访问“错误:19 - 物理连接不可用”的主要内容,如果未能解决你的问题,请参考以下文章
Azure OpenID Connect 通过 OWIN 中间件导致无限重定向循环
openid connect owin 如何验证来自 Azure AD 的令牌?
如何将 Azure OpenIdConnect OWIN 中间件 Cookie Auth 转换为 SPA 应用程序的 JavaScript JWT?