我有一个多会话数据库。很少有会话向数据库插入许多行。并且从该表中选择一个会话。
有时我在 SELECT 查询上遇到死锁,我不明白为什么。
例如:假设这个表
Create Table t1([id] int identity(1,1), [column] varchar(max))
插入是这样的:(我是从“后”触发器开始的)
Begin Transaction
Insert into t1 WITH (TABLOCKX) ([column]) values ('value 1'), ('value 2') ... ('value N')
Commit Transaction
选择是这样的:
Select TOP 10 [id],[column] from t1 order by id
插入锁定意味着保持数据库中会话插入的顺序。
每次我在事务中只锁定一个表。我试图通过插入一个会话并选择第二个会话来恢复死锁,但我失败了。在添加 TABLOCKX 之前,我从未遇到过死锁。
所以我的问题是:
- 怎么可能出现僵局?(也许在嵌套事务中?)
- MSSQL 中是否有一个选项可以以不阻止选择的方式执行写锁定?
- 有什么想法可以防止死锁吗?(但在数据库中保持会话插入序列不变......)
如果没有查询或死锁图,我不能说太多关于你的死锁。
您指定排他表锁有什么原因吗?
SQL Server 非常擅长将锁从行或页升级到表本身。
是的,您可以启用READ COMMITTED SNAPSHOT ISOLATION LEVEL。
使用此隔离级别,您始终可以读取已提交的内容。如果此时正在写入另一个查询,您将看到所写入内容的最新快照。
请通读 MSDN 页面,看看 RCSIL 是否适用于您的应用程序。