Sql 在select语句的update块中使用(NOLOCK,READUNCOMMIT)是否正确?
请帮助我,我在update块的select语句中使用(NOLOCK,READUNCOMMITED)是否正确?Sql 在select语句的update块中使用(NOLOCK,READUNCOMMIT)是否正确?,sql,sql-server,stored-procedures,Sql,Sql Server,Stored Procedures,请帮助我,我在update块的select语句中使用(NOLOCK,READUNCOMMITED)是否正确? 我需要这样做是为了报告的目的,但我不知道它是否正确 如果不理解NOLOCK提示为什么放在那里,就很难判断它是否正确 其目的是它不会放置行/页锁,也不应该被阻止读取,但它不会完全阻止锁定,因为仍然会发出Sch-S锁(模式稳定性锁) 无锁是有代价的,但是,您可以读取未限制/脏数据,并且不具有事务一致性,从理论上讲,NOLOCK甚至可以读取同一行两次 未提交的提示没有意义,因为这不是一个有效的
我需要这样做是为了报告的目的,但我不知道它是否正确 如果不理解NOLOCK提示为什么放在那里,就很难判断它是否正确 其目的是它不会放置行/页锁,也不应该被阻止读取,但它不会完全阻止锁定,因为仍然会发出Sch-S锁(模式稳定性锁) 无锁是有代价的,但是,您可以读取未限制/脏数据,并且不具有事务一致性,从理论上讲,NOLOCK甚至可以读取同一行两次 未提交的提示没有意义,因为这不是一个有效的提示-它可能应该是readuncommitted,这是指定NOLOCK的另一种方式-因此该部分似乎没有意义。根据: 不能为通过insert、update或delete操作修改的表指定READUNCOMMITED和NOLOCK。SQL Server查询优化器将忽略FROM子句中应用于UPDATE或DELETE语句的目标表的READUNCOMMITED和NOLOCK提示 表
Fireball..Position
和Fireball\u Reporting..PositionMaster
未修改,因此此提示应该可以
编辑:
我假设您希望写入
READUNCOMMITTED
而不是UNCOMMITTED
readcommitted
也可以读取同一行两次,但可能性较小。您需要REPEATABLEREAD
来完全避免这种可能性,如果在扫描过程中使用update
更改索引键,仍然可能会漏行。@Martin-在扫描运行时通过更新上的页面分割?否。页面分割将影响nolock
可能使用的分配顺序扫描。如果在索引顺序扫描期间更新了键,则可以将该行移动到索引中的稍后位置并读取两次。这是有意义的-我记得Lubor Koller曾在一段时间前写过一篇关于NOLOCK和double reads的文章,其中他详细描述了场景。我们不知道还有什么在修改报告时修改Position和Position masterrunning@Andrew,你对整个报告的看法是对的。我的答案仅基于所显示的查询。是的,我正在考虑(NOLOCK,READUNCOMMITTED)我只是想知道我如何使用它是否正确?因为它在update块中,但对于select语句?我认为这是正确的,直到您接受来自这些表的脏读取,因为:没有发出共享锁来防止其他事务修改当前事务读取的数据,其他事务设置的独占锁不会阻止当前事务读取锁定的数据。
UPDATE
BondPrices
SET
MarketValueOwned = Holdings.Amount
FROM
BondPrices BondPrices
INNER JOIN
(
SELECT
PM.SecurityId,
SUM(Pos.QuantityTraded * Pos.Mark) AS Amount
FROM
Position Pos --WITH (NOLOCK, READUNCOMMITTED)
INNER JOIN
PositionMaster PM --WITH (NOLOCK, READUNCOMMITTED)
ON
Pos.PositionMasterId = PM.PositionMasterId
WHERE
Pos.Date = @ReportDate
GROUP BY
PM.SecurityId
) Holdings ON
BondPrices.SecurityId = Holdings.SecurityId
WHERE
BondPrices.Date = @ReportDate