所以我有一个问题让我陷入困境。熟悉系统的人无法弄清楚为什么sproc会死锁,但他们告诉我我应该把它添加到它:
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
这真的是一个有效的解决方案吗?那是做什么的?
答案 0 :(得分:6)
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
这将导致系统返回不一致的数据,包括重复记录和丢失记录。请阅读Previously committed rows might be missed if NOLOCK hint is used或Timebomb - The Consistency problem with NOLOCK / READ UNCOMMITTED。
如果您遵循正确的程序,可以调查和修复死锁,这不是什么大问题。当然,扔一个肮脏的阅读可能看起来更容易,但在路上,你会长时间盯着你的总账,并想知道为什么这样做不平衡借记和信用。所以请再读一遍,直到你真的理解这一点:脏读不一致。
如果您想获得监狱卡,请启用snapshot isolation:
ALTER DATABASE MyDatabase
SET READ_COMMITTED_SNAPSHOT ON
但请记住,快照隔离不修复死锁,它只隐藏它们。正确调查死锁原因和修复始终是适当的操作。
答案 1 :(得分:5)
答案 2 :(得分:3)
向查询中随机添加SET
选项不太可能帮助我害怕
SET NOCOUNT ON
对此问题没有任何影响。
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
将阻止您的查询取出共享锁。除了读取“脏”数据之外,它还可以导致您的查询读取相同的行两次,或者根本不读取,这取决于正在发生的其他并发活动。
这是否能解决死锁问题取决于死锁的类型。如果由于锁定请求的非线性排序导致2个写入器死锁,则它将完全没有效果。 (事务1更新行a,事务2更新行b然后tran 1请求锁定b和tran 2请求锁定a)
你能发布有问题的查询和死锁图吗? (如果您使用的是SQL 2005或更高版本)
答案 3 :(得分:2)
最佳指南是:
http://technet.microsoft.com/es-es/library/ms173763.aspx
段:
指定语句可以读取已被其他人修改的行 交易但尚未提交。
在READ上运行的事务 未达到的水平不会分享 锁定以防止其他事务 从修改数据读取 当前交易。阅读不满意 交易也不会被阻止 独家锁定会阻止 读取行的当前事务 已被修改但没有 由其他交易承诺。什么时候 此选项已设置,可以 读取未提交的修改,其中 被称为脏读。价值观 数据可以更改,行可以 在数据集中出现或消失 在交易结束之前。 此选项具有相同的效果 在所有表中设置NOLOCK 事务中的SELECT语句。 这是最不受限制的 隔离级别。
在SQL Server中,您也可以最小化 保护时锁定争用 来自脏读的交易 使用未提交的数据修改 之一:
READ COMMITTED隔离级别 使用READ_COMMITTED_SNAPSHOT 数据库选项设置为ON。该 SNAPSHOT隔离级别
答案 4 :(得分:0)
另一方面,还有两个方面需要考虑,这可能有所帮助。
1)索引和SQL使用的索引。表上使用的索引策略将影响受影响的行数。如果使用唯一索引进行数据修改,则可以减少死锁的可能性。
一种算法 - 当然它不适用于所有情况。使用NOLOCK是有针对性的,而不是全球性的。
The "old" way:
UPDATE dbo.change_table
SET somecol = newval
WHERE non_unique_value = 'something'
The "new" way:
INSERT INTO #temp_table
SELECT uid FROM dbo.change_table WITH (NOLOCK)
WHERE non_unique_value = 'something'
UPDATE dbo.change_table
SET somecol = newval
FROM dbo.change_table c
INNER JOIN
#temp_table t
ON (c.uid = t.uid)
2)交易持续时间 交易开放的时间越长,可能存在争用的可能性越大。如果有办法减少记录保持锁定的时间,则可以减少发生死锁的可能性。 例如,在代码的开头执行尽可能多的SELECT语句(例如查找),而不是执行INSERT或UPDATE,然后执行查找,然后执行INSERT,然后执行另一次查找。 这是可以在“静态”表上使用NOLOCK提示选择SELECT,而不会改变代码的锁定“足迹”。