SQL SERVER에서 전체 테이블을 잠그는 선택이 있습니다.
설정 스크립트는 다음과 같습니다 (아무것도 덮어 쓰지 않도록하십시오)
USE [master]
GO
IF EXISTS(SELECT 1 FROM sys.databases d WHERE d.name = 'LockingTestDB')
DROP DATABASE LockingTestDB
GO
CREATE DATABASE LockingTestDB
GO
USE [LockingTestDB]
GO
IF EXISTS(SELECT 1 FROM sys.tables t WHERE t.name = 'LockingTestTable')
DROP TABLE LockingTestTable
GO
CREATE TABLE LockingTestTable (
Id int IDENTITY(1, 1),
Name varchar(100),
PRIMARY KEY CLUSTERED (Id)
)
GO
INSERT INTO LockingTestTable(Name) VALUES ('1')
INSERT INTO LockingTestTable(Name) VALUES ('2')
GO
새 쿼리 창을 열고 대기중인 다음 트랜잭션을 실행하십시오.
USE [LockingTestDB]
GO
BEGIN TRANSACTION
SELECT * FROM LockingTestTable t WITH (UPDLOCK, ROWLOCK) WHERE t.Name = '1'
WAITFOR DELAY '00:01:00'
COMMIT TRANSACTION
--ROLLBACK
GO
USE [master]
GO
그리고 다른 하나가 실행될 것입니다 (동시에 실행하십시오).
USE [LockingTestDB]
GO
SELECT * FROM LockingTestTable t WITH (UPDLOCK, ROWLOCK) WHERE t.Name = '2'
USE [master]
GO
두 번째 쿼리는 첫 번째 쿼리에 의해 차단됩니다. 첫 번째 쿼리를 중지하고 ROLLBACK을 실행하면 두 번째 쿼리가 완료됩니다.
왜 이런 일이 발생합니까?
추신 : Name에 클러스터되지 않은 인덱스 (전체 범위 포함)를 추가하면 수정됩니다.
USE [LockingTestDB]
GO
CREATE NONCLUSTERED INDEX [IX_Name] ON [dbo].[LockingTestTable]
(
[Name] ASC
)
INCLUDE ( [Id]) WITH (STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
또 왜?