使用 READ UNCOMMITTED 隔离级别的最佳情况

11 sql-server deadlock concurrency isolation-level

众所周知,READ UNCOMMITTED 是最低的隔离级别,在该级别中可能会产生脏读和幻读之类的事情。何时是使用此隔离级别的最佳时间,可能出于什么原因使用它?

其实我之前看过答案,但是因为例子不够,所以没能完全理解。

Dan*_*man 22

我使用READ_UNCOMMITTED(或NOLOCK在从 SSMS 查询生产数据库时),但不经常从应用程序代码查询。这种做法(连同 MAXDOP 1 查询提示)有助于确保数据分析和故障排除的临时查询不会影响生产工作负载,因为了解结果可能不正确。

可悲的是,我看到READ_UNCOMMITTED/NOLOCK在生产代码中广泛使用以避免以牺牲数据完整性为代价的阻塞。正确的解决方案是行版本隔离级别(SNAPSHOTREAD_COMMITTED使用READ_COMMITTED_SNAPSHOT数据库选项ON)和/或注意查询和索引调整。

我最近代码审查了一个过程,其中唯一的变化是删除,NOLOCK因为它有时会返回错误的结果。删除NOLOCK是一件好事,但是,知道丢失或重复的行通常发生在大表的分配顺序扫描期间,我还建议重构以使用一种UNION ALL技术来提高索引的使用效率。查询现在在几毫秒内运行并获得正确的结果,这是世界上最好的。


Eri*_*ing 7

我认为在某些情况下是可以的,只要你接受后果,别无选择。

对于其他选项,我会推动人们对新应用程序使用读提交快照隔离 (RCSI),或对旧应用程序使用快照隔离 (SI),在这些应用程序中,您无法使用 RCSI 轻松测试整个代码库的竞争条件。

但是,这些可能不太合适。您可能需要花一些额外的时间来爱护和关心 tempdb,并确保没有人留下一个打开的事务,从而使版本存储(和 tempdb)增长并填满磁盘。

如果您没有 DBA 或负责监视和管理您的 SQL Server 的人员,那么这些选项可能是危险的。更一般地说,并不是每个人都可以完全控制进入他们服务器的代码,他们可以在其中更改连接字符串或代码以请求 SI 进行问题查询。

除此之外,大多数人的整个应用程序都没有锁定问题。他们在报告 OLTP 数据等方面存在问题。如果您可以接受 NOLOCK/RU 的权衡以换取那些未被作者阻止的报告,那就去做吧。

只要确保你明白这意味着什么。这并不意味着您的查询不需要任何锁,而是意味着它不尊重其他查询取出的锁。

当然,如果您的问题是写入器/写入器锁定,那么唯一有帮助的选项是 SI,但是开发人员需要花费大量的工作才能通过错误处理等正确实现它。


Gai*_*ius 5

恕我直言,在现代系统上 READ UNCOMMITTED的唯一有效用例是在开发中从另一个会话调试一个会话时,因此您可以在例如存储过程仍在运行时看到它在做什么。它通常不会在生产系统中使用。可能会有一些小的性能提升,但从长远来看,它永远不值得。