Sql server SQL Server在非聚集索引上锁定
我在使用MS SQL Server 2008 R2的一个数据库实例时遇到了大麻烦!我创建了下面的结构来模拟我的真实问题Sql server SQL Server在非聚集索引上锁定,sql-server,sql-server-2008,sql-server-2008-r2,locking,Sql Server,Sql Server 2008,Sql Server 2008 R2,Locking,我在使用MS SQL Server 2008 R2的一个数据库实例时遇到了大麻烦!我创建了下面的结构来模拟我的真实问题 USE [sor] GO ALTER DATABASE [sor] SET ALLOW_SNAPSHOT_ISOLATION on; ALTER DATABASE [sor] SET READ_COMMITTED_SNAPSHOT on; CREATE TABLE [dbo].[test] ( [name] [nvarchar](50) NOT NULL,
USE [sor]
GO
ALTER DATABASE [sor] SET ALLOW_SNAPSHOT_ISOLATION on;
ALTER DATABASE [sor] SET READ_COMMITTED_SNAPSHOT on;
CREATE TABLE [dbo].[test] (
[name] [nvarchar](50) NOT NULL,
[id] [int] NOT NULL,
CONSTRAINT [PK_test] PRIMARY KEY CLUSTERED ([id] 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
CREATE NONCLUSTERED INDEX [IX_test] ON [dbo].[test] (
[name] ASC
) WITH (PAD_INDEX = OFF, 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
ALTER TABLE [dbo].[test] ADD CONSTRAINT [PK_test] PRIMARY KEY CLUSTERED (
[id] ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
CREATE UNIQUE NONCLUSTERED INDEX [pk_key] ON [dbo].[test] (
[id] ASC
) WITH (PAD_INDEX = OFF, 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
我的问题是,当我同时执行两个或多个会话(事务)时,我被一些数据库索引锁定。为了模拟它,我启动一个sqlcmd
:
-- sqlcmd 1
begin tran s1
insert into dbo.test (id, name) values(1, 'bob');
go
并启动另一个sqlcmd
作为下一个并发事务:
-- sqlcmd 2
begin tran s2
insert into dbo.test (id, name) values(2, 'john');
go -- locking here!!!!
当我在名为s2的事务中运行go
时,我被锁定。
为了发现发生了什么,我跑步
从sys.dm_exec_请求中选择*,其中DB_NAME(database_id)='sor'和blocking_session_id 0
跑步
SELECT t1.resource_type, t1.resource_database_id, t1.resource_associated_entity_id, t1.request_mode, t1.request_session_id, t2.blocking_session_id, o1.name 'object name', o1.type_desc 'object descr', p1.partition_id 'partition id', p1.rows 'partition/page rows', a1.type_desc 'index descr', a1.container_id 'index/page container_id' FROM sys.dm_tran_locks as t1 INNER JOIN sys.dm_os_waiting_tasks as t2 ON t1.lock_owner_address = t2.resource_address LEFT OUTER JOIN sys.objects o1 on o1.object_id = t1.resource_associated_entity_id LEFT OUTER JOIN sys.partitions p1 on p1.hobt_id = t1.resource_associated_entity_id LEFT OUTER JOIN sys.allocation_units a1 on a1.allocation_unit_id = t1.resource_associated_entity_id
我有以下几点
resource_type resource_database_id resource_associated_entity_id request_mode request_session_id blocking_session_id object name object descr partition id partition/page rows index descr index/page container_id
---------------- -------------------- ----------------------------- -------------- ------------------ ------------------- ------------- ------------- ------------- -------------------- -------------- -----------------------
KEY 23 72057594038910976 X 74 73 NULL NULL NULL NULL IN_ROW_DATA 72057594038255616
使用READ Committed SNAPSHOT后,我会问您为什么sql server会锁定索引?我能做什么我无法删除索引!我需要它们。外面有很多信息,但是马丁·史密斯对这个问题的回答可能会有所启发: 看起来,如果启用了锁定,并且表中可能只有0或1条记录,那么整个表将被有效地锁定 对于现实生活中的问题,您要在表中插入多少条目?另外,是否有额外的代码导致锁被保持的时间比可能的时间长得多
resource_type resource_database_id resource_associated_entity_id request_mode request_session_id blocking_session_id object name object descr partition id partition/page rows index descr index/page container_id
---------------- -------------------- ----------------------------- -------------- ------------------ ------------------- ------------- ------------- ------------- -------------------- -------------- -----------------------
KEY 23 72057594038910976 X 74 73 NULL NULL NULL NULL IN_ROW_DATA 72057594038255616