我今天注意到我的应用程序出现了一些错误,它试图在表中插入一条记录,并且由于暂时的网络延迟而收到超时错误。该应用程序的编码是为了识别这种情况,并在这种情况下重试,而这种情况很顺利。但是在重试时,它经历了主键违例 - 主要是因为第一个插入语句实际上已经完成,但是发生了超时而将响应传送回客户端。应用程序认为主键违规是严重的逻辑错误,不应该发生,因此会中止整个过程。什么层应该负责处理超时到SQL Server的逻辑负责?
对我来说问题是什么层在逻辑上应该负责处理这类事情?理想情况下,我会认为SQL客户端库(在本例中为ADO.NET 4.0)应该这样做,但它没有我知道的自动重试机制。鉴于它没有,似乎有可能在SQL客户端库的低级别包装器,但我不知道如果没有更多的访问有关超时发生时间的信息,它可以被写入:例如,在这种例子中,可能的做法是:a)INSERT语句只是使用自动递增键插入新记录,因此在超时后重试会导致插入重复记录,或b)主键违规事实上是一个逻辑错误,并且如果没有发生超时,初始尝试插入一条记录会产生相同的违规行为
OTOH我确信我能想到的例子是否只能确定是否重试在应用程序级别(尤其是如果它需要用户确认的话)。
我实际上有些惊讶我以前从来没有见过这个特别的错误序列,因为它在实践中似乎很有可能。
'XACT_ABORT'实际上与客户端遇到运行时错误无关。它与语句的执行环境遇到运行时错误有关。如果事务遇到运行时错误(在服务器上),那么它将中止并回滚整个事务。您的客户端库(如.NET中包含的库)会由于缺陷而遇到运行时错误,并且SQL Server上的事务仍可能成功。 “XACT_ABORT”很可能不是默认的简单符合OLE DB常见做法;原因可能是因为一些性能的提升。 – 2014-02-19 04:22:26