2013-04-23 60 views
0

我今天注意到我的应用程序出现了一些错误,它试图在表中插入一条记录,并且由于暂时的网络延迟而收到超时错误。该应用程序的编码是为了识别这种情况,并在这种情况下重试,而这种情况很顺利。但是在重试时,它经历了主键违例 - 主要是因为第一个插入语句实际上已经完成,但是发生了超时而将响应传送回客户端。应用程序认为主键违规是严重的逻辑错误,不应该发生,因此会中止整个过程。什么层应该负责处理超时到SQL Server的逻辑负责?

对我来说问题是什么层在逻辑上应该负责处理这类事情?理想情况下,我会认为SQL客户端库(在本例中为ADO.NET 4.0)应该这样做,但它没有我知道的自动重试机制。鉴于它没有,似乎有可能在SQL客户端库的低级别包装器,但我不知道如果没有更多的访问有关超时发生时间的信息,它可以被写入:例如,在这种例子中,可能的做法是:a)INSERT语句只是使用自动递增键插入新记录,因此在超时后重试会导致插入重复记录,或b)主键违规事实上是一个逻辑错误,并且如果没有发生超时,初始尝试插入一条记录会产生相同的违规行为

OTOH我确信我能想到的例子是否只能确定是否重试在应用程序级别(尤其是如果它需要用户确认的话)。

我实际上有些惊讶我以前从来没有见过这个特别的错误序列,因为它在实践中似乎很有可能。

回答

0

显然这个特定问题的解决方案是使用'SET XACT_ABORT ON'。 据报道,如果客户机上存在运行时错误,则会导致SQL Server回滚语句。我很好奇为什么它不是实际的默认行为。

+0

'XACT_ABORT'实际上与客户端遇到运行时错误无关。它与语句的执行环境遇到运行时错误有关。如果事务遇到运行时错误(在服务器上),那么它将中止并回滚整个事务。您的客户端库(如.NET中包含的库)会由于缺陷而遇到运行时错误,并且SQL Server上的事务仍可能成功。 “XACT_ABORT”很可能不是默认的简单符合OLE DB常见做法;原因可能是因为一些性能的提升。 – 2014-02-19 04:22:26

0

IDENTITY财产does not guarantee uniqueness,永远。这意味着当您在给定的表上并发INSERT语句时,您的自动递增值可能会在多个活动事务中复制。

解决此问题的一种方法是在开始交易之前发出SET TRANSACTION ISOLATION LEVEL SERIALIZABLE声明。这将防止冲突的插入,意味着没有两个插入可以并行执行。

另一种更常见的方式是简单地重新尝试您的事务或语句,直到您没有收到主键违例为止。这应该只在您不执行身份插入并且让SQL Server处理主键值并且它是自动递增的情况下完成。

另一种以某种可接受的方式处理此问题的方法是使用UNIQUEIDENTIFIER类型的主键。这些几乎保证是独一无二的。你可以在很长一段时间后,开始接收重复;这将需要与重试相同的逻辑,并且会丢失主键索引的物理布局优化。这是一个替代或注释,而不是建议。

总而言之,如果你想处理错误和你使用的是SQL Server 2012中,你可以简单地使用下面的模板,以确保您的交易是适当的回滚和错误移动到表面:

BEGIN 
    SET NOCOUNT ON; 
    SET XACT_ABORT OFF; 

    BEGIN TRANSACTION; 
     BEGIN TRY 
      -- Do stuff here 
     END TRY 
     BEGIN CATCH 
      ROLLBACK TRANSACTION; 
      THROW; 
     END CATCH 

    COMMIT TRANSACTION; 
END 

另请注意,此模板不适用于存储过程的嵌套调用,如果以该方式使用,将回滚整个过程链。

编辑

由于您使用ADO .NET,您可以禁用连接池和照顾连接管理自己。如果一个连接超时池化关闭,它会在服务器端发生故障并销毁事务,导致回滚。

+0

虽然我没有说我使用了IDENTITY,但我的交易一次只能插入一条记录。服务器端没有发生错误 - 它在等待响应时位于客户端。服务器无法确定客户端在最终提交更改时没有抛出异常,所以我没有看到任何基于服务器的解决方案是如何工作的。真的,我能看到的唯一解决方案是在超时异常之后检查客户端是否实际插入了记录。 – 2014-02-19 00:00:21

+0

@DylanNicholson很难确定你的过程失败的是什么点。你提到了一个超时错误,然后重试了一次,但指出即使使用了自动递增键,也会遇到一个主键冲突,因此会出现'IDENTITY'列或某种设计,其中应用程序负责自动递增。在后一种情况下,我会争辩说你应该在服务器端放置自动递增行为。据说,我指出了许多不同的解决方案来从多个角度对付你的问题。 – 2014-02-19 04:13:16