我想减少服务器上的锁定,因为我的应用程序中的某些用户拥有对数据库的直接权限,并且他们执行不带NOLOCK
的查询,这会在数据库中创建锁。
为了减少这种情况,我想为数据库创建一个新的模式,在这个模式中,我将为数据库中的所有表创建视图。在这个视图中,我将写为:
select * from TABLE_NAME(nolock).
然后我将仅为此架构授予用户权限,这样可以减少锁定。
这种方法是一种好方法吗?它会在数据库中产生开销吗?
请建议。
答案 0 :(得分:1)
来自NOLOCK
上的BOL(READUNCOMMITED
)提示:
指定允许脏读。没有发布共享锁 防止其他事务修改当前读取的数据 事务和其他事务设置的独占锁不会 阻止当前事务读取锁定数据。允许 脏读可以导致更高的并发性,但代价是阅读 然后由其他事务回滚的数据修改。 这可能会为您的交易产生错误,为用户提供数据 从未提交,或导致用户两次(或不是) 在所有)。
如果这是您可以接受的,您可以考虑您的方法。当然它会加快所有查询的性能。但是我必须说这不是一个好主意,因为它可能导致许多其他不可预测的错误 - 如果你使用NOLOCK
读取数据用于以后的操作。
Here is a nice blog pos关于使用NOLOCK
的危险以及您可以实施的其他可能的解决方案,以避免使用它。
答案 1 :(得分:0)
没有。你的方法在很多层面都存在缺陷。至少你需要注意两个问题:
READUNCOMMITTED和NOLOCK提示仅适用于数据锁。所有查询(包括具有READUNCOMMITTED和NOLOCK提示的查询)在编译和执行期间都会获取Sch-S(模式稳定性)锁。因此,当并发事务在表上持有Sch-M(模式修改)锁时,将阻止查询。
您应该考虑两种选择:
最好为这些用户创建数据库的备用只读副本以运行其查询。您可以使用AG readable secondaries(奢侈品选项),待机log shipping数据库,本地database snapshot或作为最后一个选项replication。
作为数据库中的替代启用read committed snapshot,让行版本控制消除争用。这可能是让用户查询备用数据的一个更糟糕的选择,因为行版本控制消耗资源,并且因为访问读写数据的用户可能会意外地最终修改数据甚至修改架构。
无论你选择什么,只要确保你摆脱NOLOCK。它没有用,它不起作用。