如何处理 SqlConnection 中的传输级错误?

How do you deal with transport-level errors in SqlConnection?

提问人:Eric Z Beard 提问时间:8/20/2008 最后编辑:nobodyEric Z Beard 更新时间:5/11/2016 访问量:27014

问:

在大容量 .NET 应用程序中,当您尝试执行查询时,您可能会看到以下异常:

System.Data.SqlClient.SqlException:传输级错误具有 在向服务器发送请求时发生。

根据我的研究,这是“刚刚发生”的事情,没有太多可以阻止它。它不会由于错误的查询而发生,并且通常无法复制。在繁忙的 OLTP 系统中,当与数据库的 TCP 连接由于某种原因而损坏时,它可能每隔几天就会出现一次。

我被迫通过解析异常消息来检测此错误,然后从头开始重试整个操作,以包括使用新连接。这些都不漂亮。

有人有其他解决方案吗?

C# ado.net SQL-Server-2000

评论

0赞 John Christensen 8/20/2008
当抛出这些错误时,是否有数据库服务器上负载的统计信息?您可能存在一些导致连接失败的数据库问题。
1赞 Portman 8/22/2008
即使在高交易量下,也不应该发生这种情况。我们在 SQL Server 2005 Standard 上平均每秒运行 25,000 个事务,并且没有收到此错误。(除非群集故障转移,即每 12+ 个月一次,而不是每隔几天一次。如果没有更多信息,听起来数据库服务器和应用程序服务器之间存在网络问题。你能发布更多信息吗?
0赞 Eric Z Beard 8/24/2008
@Portman,我怀疑这是由于我被迫使用的蹩脚的板载戴尔 NIC,因为我的两个 PCIe 插槽都被连接到 DAS 的 HBA 卡占用了。我正在升级到更大的机器,以便我可以安装(更好的)英特尔 NIC。如何使用 Standard Edition 进行群集?这是企业版的一项功能。
0赞 Portman 8/27/2008
群集、日志传送和镜像在 Standard 中都可用。http://www.microsoft.com/sql/prodinfo/features/compare-features.mspx
0赞 Joshua 8/20/2010
据我所知,20 级是运输级别。

答:

0赞 Kevin Goff 8/20/2008 #1

还应检查与数据库的硬件连接。

也许这个线程会有所帮助:http://channel9.msdn.com/forums/TechOff/234271-Conenction-forcibly-closed-SQL-2005/

0赞 Rinat Abdullin 10/1/2008 #2

我在我的数据库命令周围使用可靠性层(在存储库界面中抽象出来)。基本上,这只是拦截任何预期异常(DbException 和 InvalidOperationException,碰巧在连接问题时引发)、记录它、捕获统计信息并重试所有操作的代码。

有了这个可靠性层,该服务就能够优雅地通过压力测试(持续的死锁、网络故障等)。生产远没有那么敌对。

PS:这里还有更多内容(以及使用拦截DSL定义可靠性的简单方法)

2赞 Daniel Fortunov 10/1/2008 #3

要回答您的原始问题,请执行以下操作:

在不分析错误消息的情况下检测此特定错误的一种更优雅的方法是检查 的属性。NumberSqlException

(这实际上返回集合中第一个错误号,但在本例中,传输错误应该是集合中唯一的错误。SqlErrorErrors

0赞 Jesper Blad Jensen 10/1/2008 #4

我有同样的问题。我问了我的网络极客朋友,他们都说了人们在这里回答的:它是计算机和数据库服务器之间的连接。就我而言,是我的互联网服务提供商,或者路由器是问题所在。路由器更新后,问题消失了。但是,您的计算机或服务器是否有任何其他互联网连接中断?我有...

9赞 Tim Farley 10/16/2008 #5

我发布了关于另一个主题的另一个问题的答案,这个问题可能在这里有一些用处。该答案涉及 SMB 连接,而不是 SQL。但是,它是相同的,因为它涉及低级传输错误。

我们发现,在高负载情况下,远程服务器很容易仅仅因为服务器繁忙而在 TCP 层超时。部分原因是TCP在Windows上重新传输数据的次数的默认值不适合我们的情况。

查看用于在 Windows 上调整 TCP/IP 的注册表设置。具体而言,您需要查看 TcpMaxDataRetransmissions,也许还有 TcpMaxConnectRetransmissions它们分别默认为 5 和 2,尝试在客户端系统上稍微增加它们并复制负载情况。

不要发疯!TCP 在每次连续重新传输时都会使超时时间增加一倍,因此,如果将超时时间增加太多,不良连接的超时行为可能会呈指数级增长。我记得,在绝大多数情况下,将 TcpMaxDataRetransmissions 增加到 6 或 7 解决了我们的问题。

1赞 Dale Wright 10/31/2008 #6

我已经在自己的环境中多次看到这种情况发生。在这种情况下,客户端应用程序安装在许多计算机上。其中一些机器恰好是笔记本电脑,人们打开应用程序,断开它,然后重新插入并尝试使用它。然后,这将导致您提到的错误。

我的第一点是查看网络并确保服务器不在DHCP上,并更新导致此错误的IP地址。如果不是这种情况,那么您必须开始在事件日志中搜索其他与网络相关的内容。

不幸的是,如上所述,这是一个网络错误。您可以做的主要事情是使用 netmon 等工具监视连接,然后从那里返回。

祝你好运。

4赞 Magnus Lindhe 1/29/2010 #7

Michael Aspengren 的这篇博文解释了错误消息“向服务器发送请求时发生了传输级错误”。

评论

0赞 Jari Turkia 1/26/2023
博客文章的更新链接是:learn.microsoft.com/en-us/archive/blogs/spike/...
1赞 Martin 7/23/2010 #8

我遇到了同样的问题,尽管它是对 SQL 数据库的服务请求。

这是我在服务错误日志中的内容:


System.Data.SqlClient.SqlException:向服务器发送请求时发生传输级错误。(提供程序:TCP 提供程序,错误:0 - 远程主机强行关闭了现有连接。


我有一个测试服务的 C# 测试套件。服务和数据库都在外部服务器上,所以我认为这可能是问题所在。所以我在本地部署了服务和数据库,但无济于事。问题仍在继续。测试套件甚至根本不是一个硬性的性能测试,所以我不知道发生了什么。每次都失败了相同的测试,但是当我禁用该测试时,另一个测试将持续失败。

我尝试了互联网上建议的其他方法,但也没有奏效:

  • 增加 TcpMaxDataRetransmissionsTcpMaxConnectRetransmissions 的注册表值。
  • 在 SQL Server 配置管理器中的“客户端协议”下禁用“共享内存”选项,并将 TCP/IP 排序到列表中的第 1 位。
  • 当您使用大量客户端连接尝试测试可伸缩性时,可能会发生这种情况。若要解决此问题,请使用 regedit.exe 实用程序将名为 SynAttackProtect 的新 DWORD 值添加到注册表项 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\ 的值数据为 00000000。

我最后的手段是用老年说“再试一次”。因此,我嵌套了 try-catch 语句,以确保如果 TCP/IP 连接在较低的通信协议中丢失,它不仅会放弃那里,还会再次尝试。这现在对我有用,但这不是一个非常优雅的解决方案。

评论

0赞 TheLegendaryCopyCoder 11/26/2015
感谢您的反馈。如果您使用的是连接池,请尝试每隔 10 分钟调用一次 SqlConnection.Recycle(),以确保如果 SQLServer 终止了连接,您的池不会继续尝试使用它。如果这可行,请报告!
1赞 Jon Black 7/23/2010 #9

将企业服务与事务组件配合使用

0赞 Phillip Deneka 3/14/2014 #10

今天早上,我在连接到 SQL 2008 R2 Express 时在 SSMS 中遇到了传输错误。

我正在尝试使用 \r\n 导入 CSV。我为 0x0d0x0a 编写了行终止符。当我将其更改为0x0a时,错误停止了。我可以来回更改它,看着它发生/不发生。

 BULK INSERT #t1 FROM 'C:\123\Import123.csv' WITH 
      ( FIRSTROW = 1, FIELDTERMINATOR = ',', ROWTERMINATOR = '0x0d0x0a' )

我怀疑我没有正确编写行终止符,因为当我尝试传递两个字符时,SQL 一次解析一个字符。

无论如何,这个错误已经有 4 年的历史了,但它可能会为下一个用户提供一些信息。

评论

0赞 Zastai 4/5/2016
我认为这里的问题是 rowterminator 应该是一个二进制值,对于 SQL Server,它将被写为 0x0d0a(没有第二个 0x)。
0赞 Phillip Deneka 6/7/2016
嘿!太滑了!今晚晚些时候我会尝试的!
0赞 J. J. 12/4/2015 #11

我只是想在这里发布一个对我们公司有用的修复程序,该修复程序适用于我们安装的新软件。从第 1 天开始,我们在客户端日志文件上收到以下错误:服务器无法处理请求。---> 从服务器接收结果时发生传输级错误。(提供程序:TCP 提供程序,错误:0 - 信号量超时期限已过期。---> 信号量超时期限已过。

完全解决该问题的方法是在我们的交换机上设置链路聚合(LAG)。我们的 Dell FX1 服务器背面有冗余光纤线路。我们没有意识到它们插入的交换机需要在这两个端口上配置 LAG。详情请见:https://docs.meraki.com/display/MS/Switch+Ports#SwitchPorts-LinkAggregation