【发布时间】:2014-11-18 19:42:42
【问题描述】:
我在负载测试场景下遇到了奇怪的行为:后端(sql server 2012)超载并且一些命令超时(这仍然是预期的,因为后端服务器是半故意的慢硬件);但我们的平台会定期(随着延迟增加)重试超时操作 - 在重试几次后,它突然开始收到“无法插入重复键”SqlException。
我验证了只能生成具有特定唯一键的单行并尝试插入(第一次插入和所有可能的重试总是发生在同一个线程上)。
我还更改了 SP,使其使用显式事务:
BEGIN TRY
BEGIN TRANSACTION;
-- Insert into table A
-- Insert into table B
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION;
THROW
END CATCH
但问题仍然存在。
有什么想法为什么会发生这种情况?
如何找出超时来自哪里(后端与客户端)?
有没有办法确保操作成功完成或失败(基本上是事务 - 但可能来自客户端代码)?
EDIT01: 我相信解决这个问题的一种方法是利用 ado.net 集成 SQL 服务器分布式事务 - 例如:
using (TransactionScope scope = new TransactionScope())
{
//Perform the sql commands
//if above statements throws (e.g. due to timeout) - than the transaction is not commited and it will be rolled back
scope.Complete()
}
但是:我同意它只会增加复杂性,实际上可能仍然反对同一个问题(usr 概述的两个将军问题)。 因此,最好的方法可能是对客户端和服务器端进行编码以依靠这样的选项 - 再次如 usr 在他的回答中所指出的那样
【问题讨论】:
-
这可能是由于sql连接中的命令超时造成的。所以我的建议是尝试手动设置 CommandTimeOut 值,因为它的默认值是 30 秒。另请参阅以下链接msdn.microsoft.com/en-us/library/…
-
请发布您的代码如何识别和重试超时操作。如果是 sqlexception,那么它来自 SQL。
-
@Blam - 是的,它是 SqlException - 但它仍然不一定意味着它来自服务器,不是吗?
-
查看调用堆栈。但是我从来没有遇到过不是 SQL 异常的 SqlException。我认为超时实际上是从 SQL 返回的。不是放弃 SQL 的命令。在 SSMS 中有一个超时设置。命令放弃 SQL 并让 SQL 旋转而没有任何连接来返回结果将是一个非常糟糕的设计。
标签: c# .net sql-server ado.net sql-server-2012