阿里云服务器有时会出现短暂的连接不上数据库服务器(RDS)的问题,之前由于没有启用 Entity Framework Core 的失败重试功能(默认是禁用的),短暂的连接失败立马会引发下面的异常从而出现500错误。

System.Data.SqlClient.SqlException (0x80131904): A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: TCP Provider, error: 40 - Could not open a connection to SQL Server)

为了解决这个问题,在 Startup 中添加如下的代码启用 RetryOnFailure 。

services.AddDbContext<CnblogsDbContext>(options =>
{
options.UseSqlServer(Configuration.GetConnectionString("cnblogs"),
builder =>
{
builder.EnableRetryOnFailure(
maxRetryCount: ,
maxRetryDelay: TimeSpan.FromSeconds(),
errorNumbersToAdd: null);
});
});

但是测试发现不起作用。

期望的测试结果是这样的:启动 asp.net core 站点 ->  curl 发请求 -> 正常响应 -> 停止 SQL Server 服务器 -> curl 发请求 -> 等待 -> 30秒之后启动 SQL Server -> 正常响应。

实际的测试结果却是这样:启动 asp.net core 站点 ->  curl 发请求 -> 正常响应 -> 停止 SQL Server 服务器 -> curl 发请求 -> 15秒左右出现500错误,报上面的异常。

难道这个异常不在 RetryOnFailure 的默认范围?

于是通过 errorNumbersToAdd 添加 0x80131904 错误码:

var errorNumer = 0x80131904;
builder.EnableRetryOnFailure(
maxRetryCount: ,
maxRetryDelay: TimeSpan.FromSeconds(),
errorNumbersToAdd: new int[] { (int)errorNumer });

却依然不起作用。

别无他法,只能硬啃 EFCore 的源代码找线索了,于是找到 SqlServerTransientExceptionDetector

public class SqlServerTransientExceptionDetector
{
public static bool ShouldRetryOn([NotNull] Exception ex)
{
if (ex is SqlException sqlException)
{
foreach (SqlError err in sqlException.Errors)
{
switch (err.Number)
{
case :
case :
case :
case :
case :
case :
case :
case :
case :
case :
case :
case :
case :
case :
case :
}
} return false;
} if (ex is TimeoutException)
{
return true;
} return false;
}
}

原来是根据 SqlError.Number 来判断的, 上面的数字都这么小,看来 0x80131904 不是 SqlError.Number ,再次查看错误日志发现在 System.Data.SqlClient.SqlException (0x80131904) 之前有下面一行日志:

Error Number:2,State:0,Class:20

原来是 2 ,于是在 errorNumbersToAdd  中添加这个 error number ,问题就解决了。

services.AddDbContext<CnblogsDbContext>(options =>
{
options.UseSqlServer(Configuration.GetConnectionString("cnblogs"),
builder =>
{
builder.EnableRetryOnFailure(
maxRetryCount: ,
maxRetryDelay: TimeSpan.FromSeconds(),
errorNumbersToAdd: new int[] { });
});
});

使用 EF Core 的 EnableRetryOnFailure 解决短暂的数据库连接失败问题的更多相关文章

  1. EF Core反向导航属性解决多对一关系

    多对一是一种很常见的关系,例如:一个班级有一个学生集合属性,同时,班级有班长.语文课代表.数学课代表等单个学生属性,如果定义2个实体类,班级SchoolClass和学生Student,那么,班级Sch ...

  2. EF Core 基础知识

    数据库连接字符串 在 ASP.NET Core 添加配置片段: { "ConnectionStrings": { "BloggingDatabase": &qu ...

  3. 张高兴的 Entity Framework Core 即学即用:(一)创建第一个 EF Core 应用

    写在前面 Entity Framework Core (EF Core) 是 .NET 平台流行的对象关系映射(ORM)框架.虽然 .NET 平台中 ORM 框架有很多,比如 Dapper.NHibe ...

  4. EntityFramework Core技术线路(EF7已经更名为EF Core,并于2016年6月底发布)

    官方文档英文地址:https://github.com/aspnet/EntityFramework/wiki/Roadmap 历经延期和更名,新版本的实体框架终于要和大家见面了,虽然还有点害羞.请大 ...

  5. 一步步学习EF Core(2.事务与日志)

    前言 上节我们留了一个问题,为什么EF Core中,我们加载班级,数据并不会出来 其实答案很简单,~ 因为在EF Core1.1.2 中我们在EF6.0+中用到的的延迟加载功能并没有被加入,不过在EF ...

  6. 一步步学习EF Core(3.EF Core2.0路线图)

    前言 这几天一直在研究EF Core的官方文档,暂时没有发现什么比较新的和EF6.x差距比较大的东西. 不过我倒是发现了EF Core的路线图更新了,下面我们就来看看 今天我们来看看最新的EF Cor ...

  7. 在.NET Core类库中使用EF Core迁移数据库到SQL Server

    前言 如果大家刚使用EntityFramework Core作为ORM框架的话,想必都会遇到数据库迁移的一些问题. 起初我是在ASP.NET Core的Web项目中进行的,但后来发现放在此处并不是很合 ...

  8. 在ASP.NET Core中通过EF Core实现一个简单的全局过滤查询

    前言 不知道大家是否和我有同样的问题: 一般在数据库的设计阶段,会制定一些默认的规则,其中有一条硬性规定就是一定不要对任何表中的数据执行delete硬删除操作,因为每条数据对我们来说都是有用的,并且是 ...

  9. EF Core下利用Mysql进行数据存储在并发访问下的数据同步问题

    小故事 在开始讲这篇文章之前,我们来说一个小故事,纯素虚构(真实的存钱逻辑并非如此) 小刘发工资后,赶忙拿着现金去银行,准备把钱存起来,而与此同时,小刘的老婆刘嫂知道小刘的品性,知道他发工资的日子,也 ...

随机推荐

  1. asp.net mvc 实战化项目之三板斧

    laravel实战化项目之三板斧 spring mvc 实战化项目之三板斧 asp.net mvc 实战化项目之三板斧 接上文希望从一张表(tb_role_info 用户角色表)的CRUD展开asp. ...

  2. PHP异步扩展Swoole笔记(2)

    dispatch_mode, 数据包分发策略 可以选择7种类型,默认为21,轮循模式,收到会轮循分配给每一个Worker进程2,固定模式,根据连接的文件描述符分配Worker.这样可以保证同一个连接发 ...

  3. string与stringBuffer区别

    string 的 “+” 操作就是根据 StringBuilder (或 StringBuffer )类及其 append 方法实现的. String 不可变其实就是说一个 String 对象创建之后 ...

  4. 【ThinkPHP】解析ThinkPHP5创建模块

    在根目录下有一个build.php文件,该文件是自动生成的,自动创建模块.build.php的文件内容如下: <?php return [ // 生成应用公共文件 '__file__' => ...

  5. Ubuntu安装守护进程supervisor

    Supervisor安装与配置(Linux/Unix进程管理工具) asp.net core 负载均衡集群搭建(centos7+nginx+supervisor+kestrel) 为了保证服务能够稳定 ...

  6. IOS应用内购(一)内购的种类

    Glossary IAP - In App Purchase, 应用内购. 内购种类 consumable - 可消费的,比如游戏中的金币,金币可以购买游戏道具或者装备,这个金币是可以消费的,用完之后 ...

  7. Django Http请求生命周期

    day54 请求响应Http 1.发送Http请求 2.服务器接收,根据请求头中的的url在路由关系表中进行匹配(从上到下) 3.匹配成功后,执行指定的views函数 4.业务处理 URL----&g ...

  8. jquery $('#form1').serialize()序列化提交表单

    1.$("#form1").serialize() 把form表单的值序列化成一个字符串,如username=admin&password=admin123 <for ...

  9. 【iCore1S 双核心板_ARM】例程十六:USB_MSC实验——虚拟U盘

    实验步骤: 1.将SD卡插在SD卡槽中. 2.将跳线冒跳至USB_Device,将USB_Device通过Micor USB线与USB主机(电脑)相连. 3.烧写程序,我的电脑中将出现一个磁盘. 实验 ...

  10. 资源查找器PathMatchingResourcePatternResolver的使用

    资源查找器PathMatchingResourcePatternResolver的使用 PathMatchingResourcePatternResolver是一个Ant通配符模式的Resource查 ...