我们都知道,读未提交是最低的隔离级别,比如脏读和幻影读取可能会发生。何时才是使用此隔离级别的最佳时机?出于什么原因可以使用此隔离级别?
其实我以前读过答案,但我不能完全理解,因为没有足够的例子。
发布于 2018-05-11 13:27:38
我在从SSMS查询生产数据库时使用READ_UNCOMMITTED (或NOLOCK),而不是常规地从应用程序代码查询。此实践(以及MAXDOP 1查询提示)有助于确保用于数据分析和故障排除的临时查询不会影响生产工作负载,而理解结果可能不正确。
遗憾的是,我看到READ_UNCOMMITTED/NOLOCK在生产代码中被广泛使用,以避免以牺牲数据完整性为代价进行阻塞。正确的解决方案是行版本控制隔离级别(SNAPSHOT或READ_COMMITTED,带有READ_COMMITTED_SNAPSHOT数据库选项ON)和/或注意查询和索引调优。
我最近的代码检查了一个proc,其中唯一的更改是删除NOLOCK,因为它有时返回错误的结果。删除NOLOCK是一件好事,但我知道丢失或重复的行通常发生在大型表的分配顺序扫描中,因此我还建议使用UNION ALL技术进行重构,以促进高效的索引使用。现在,这个查询在几毫秒内运行,得到了正确的结果,这是所有世界中最好的。
发布于 2018-05-11 13:55:30
我认为在某些情况下,这是好的,只要你接受后果,没有其他选择。
对于其他选项,我会推动人们使用ReadCommitedSnap快照隔离( RCSI )用于新应用程序,或者使用快照隔离(SI)更早的应用程序,在这些应用程序中,您无法轻松地使用RCSI测试整个代码库的争用条件。
然而,这可能不是一个很好的选择。您可能需要花一些额外的时间来热爱和关心tempdb,并确保没有人留下一个打开的事务,从而使版本存储(和tempdb)增长并填满磁盘。
如果您没有DBA,或者您的工作是监视和管理您的Server,那么这些选项可能是很危险的。更普遍的情况是,并不是每个人都能完全控制发送到服务器的代码,在那里,他们可以更改连接字符串或代码,以请求SI进行问题查询。
除此之外,大多数人在他们的整个应用程序中没有锁定问题。他们在诸如OLTP数据报告之类的事情上有问题。如果你可以接受NOLOCK/RU的权衡,以换取那些没有被作者阻止的报道,那就去做吧。
确保你明白这意味着什么。这并不意味着您的查询不接受任何锁,它意味着它不尊重其他查询提取的锁。
当然,如果您的问题是编写器/写入器的锁定,那么唯一有帮助的选择就是SI,但是要用错误处理等方法正确地实现这一点,需要花费大量的开发人员的工作。
发布于 2018-05-11 13:13:48
IMHO --现代系统中未提交读的唯一有效用例是从开发中的另一个会话中调试会话时,您可以看到它正在做什么,例如存储的proc仍在运行。它通常不会在生产系统中使用。可能会有一些小的表现,但从长远来看,这是不值得的。
https://dba.stackexchange.com/questions/206485
复制相似问题