Sql 在select语句的update块中使用(NOLOCK,READUNCOMMIT)是否正确?

Sql 在select语句的update块中使用(NOLOCK,READUNCOMMIT)是否正确?,sql,sql-server,stored-procedures,Sql,Sql Server,Stored Procedures,请帮助我,我在update块的select语句中使用(NOLOCK,READUNCOMMITED)是否正确? 我需要这样做是为了报告的目的,但我不知道它是否正确 如果不理解NOLOCK提示为什么放在那里,就很难判断它是否正确 其目的是它不会放置行/页锁,也不应该被阻止读取,但它不会完全阻止锁定,因为仍然会发出Sch-S锁(模式稳定性锁) 无锁是有代价的,但是,您可以读取未限制/脏数据,并且不具有事务一致性,从理论上讲,NOLOCK甚至可以读取同一行两次 未提交的提示没有意义,因为这不是一个有效的

请帮助我,我在update块的select语句中使用(NOLOCK,READUNCOMMITED)是否正确?
我需要这样做是为了报告的目的,但我不知道它是否正确

如果不理解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