SQL Server 是否有可能在 select * where PK = "value" 查询中遗漏行

Spe*_*nce 5 sql-server-2008-r2 transaction

我们刚刚将应用程序从 SQL Server 2005 迁移到 SQL Server 2008 R2,并从物理托管环境迁移到虚拟托管环境。

我的应用程序中有一个非常奇怪的错误,我想知道是否有人见过可能导致以下情况的情况:

表结构很简单

CREATE TABLE [dbo].[TableName](
[PKCol] [nvarchar](8) NOT NULL,
[DataCol] [nvarchar](100) NOT NULL,
CONSTRAINT [PK_TableName] PRIMARY KEY CLUSTERED 
(
    [PKCol] ASC
)
WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, 
      IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) 
ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[TableName]  
WITH CHECK ADD CONSTRAINT [FK_OtherTable] FOREIGN KEY([PKCol])
REFERENCES [dbo].[OtherTable] ([PKCol])
GO

ALTER TABLE [dbo].[TableName] CHECK CONSTRAINT [FK_OtherTable]
GO
Run Code Online (Sandbox Code Playgroud)

查询是:

SELECT PKCol, DataCol FROM TableName
WHERE PKCol = 'SomeString'
Run Code Online (Sandbox Code Playgroud)

此查询在过去 5 年中返回了测试字符串的行。在很短的时间内(2 周内 1 秒),此查询返回 0 行(对于存在于查询返回零行之前 1 秒和之后 1 秒的查询字符串)。如果它有帮助,则该表中有几十行,并且当“条件”发生时,搜索其中任何一个都会返回零行(如在不同字符串的选择查询中返回零行)。

没有对表执行插入、删除或更新。一个事务可能发生在另一个表上,该表是外键。

查询不返回任何形式的 SQL 错误,它是来自 SQL 的有效响应,它似乎指示零行,然后影响应用程序代码的行为。

我应该从哪里开始查看和/或我应该查看的知识库/修补程序的任何线索?

Rem*_*anu 9

nvarchar(8) PK NOT NULL
Run Code Online (Sandbox Code Playgroud)

... 他们的 PK 返回 null ...

这在任何情况下都不会发生。因此,我必须得出结论,您的“简化”复制已将事情简化到超出您理解范围的范围。请发布确切的表定义(包括所有索引)和您发出的确切查询。

Null 是从.FirstOrDefault()C# 中的 linq查询返回的。

好的,这改变了事情。所以,如果我们相信你的话,你会看到提交的行被跳过。在脏读隔离(或 NOLOCK 提示)下,这是一种常见现象,请参阅如果使用 NOLOCK 提示,可能会丢失先前提交的行。正如 Brent 和 Martin 在他们的评论中指出的那样,在更高的隔离级别下遇到丢失行的情况相当罕见,但并非不可能。

那你该怎么办?毕竟,如果您想针对最终一致的模型进行编程,您会选择更便宜且可能更快的东西。首先确保您没有处于脏读隔离级别。更高级别的异常情况相当罕见,因此让我们确保您不在常见的范围内。如果您确信读取发生在高于脏读的隔离级别下,那么您需要隔离该现象。同样,在此处发布确切的表定义和您运行的确切查询。

阅读了解 SQL Server 如何执行查询


Bre*_*zar 6

如果您在查询中使用 READ UNCOMMITTED 隔离级别或 WITH (NOLOCK),您的查询可以跳过行或查看行两次。

肯德拉·利特尔 (Kendra Little) 在她 30 分钟的网络广播中更详细地解释了这一点

  • 这会影响(正如 OP 声称的)很长时间没有看到任何插入、删除或更新的表吗?(好吧,OP 的说法有点矛盾,因为他“刚刚”迁移到新版本,所以所有的表都是新的而不是几年前的) (2认同)