如何确保在一张表上同时执行 INSERT 和 SELECT 不会造成死锁?

Ser*_*lov 7 sql-server deadlock

我的 SQL Server 2008 数据库中有下表:

CREATE TABLE [dbo].[SomeTable]
(
   [Id] [bigint] IDENTITY(1,1) NOT NULL,
   [Column1] [varchar](30) NOT NULL,
   [Column2] [varchar](30) NOT NULL,
   [Column3]  [varchar](50) NOT NULL,
   CONSTRAINT [PK_SomeTable] PRIMARY KEY CLUSTERED 
   (
  [Id] ASC
   )
 )
Run Code Online (Sandbox Code Playgroud)

一个进程将数据插入到该表中,另一个进程从该表中读取所有数据。两个进程同时工作。

one process:
INSERT INTO dbo.SomeTable VALUES ('col1', 'col2', 'col3')

another process:
SELECT Id, Column1, Column2, Column3 FROM dbo.SomeTable
Run Code Online (Sandbox Code Playgroud)

我看到第二个查询进行了全表扫描,但我需要从该表中获取所有数据以进行进一步处理(它不会是一个非常大的表,因为它会定期清理。它将包含 1K-2K 行)。

有没有办法确保这两个查询永远不会发生死锁?

gbn*_*gbn 7

在默认锁定策略下,死锁总是会在某个时刻发生。但是,由于直接表扫描,在您给定的场景中不太可能。

但是,如果您有多个并发 INSERT 和 SELECT,则更有可能。

使用 NOLOCK 意味着脏读并且不是最佳实践。虽然每个人似乎都建议他们...

另一种方法是使用快照隔离模式:SELECT 将读取最后提交的数据,而不是被 INSERT 阻塞。