从常量插入的表中选择

时间:2011-10-25 19:33:30

标签: sql sql-server-2008 select insert deadlock

我将如何从一个常量插入(并且需要)的表中抓取数据而不会导致任何锁定,以便插入将继续被忽略。

我环顾四周,发现选择nolock选项但是,如果我理解正确,这不会阻止锁定创建,而是绕过当前锁定并抓住所有内容?

感谢。

编辑:此表永远不会更新,只有INSERTS和SELECTS

5 个答案:

答案 0 :(得分:3)

从表格中选择时,您可以使用NOLOCK提示。有这样的副作用(你基本上可以得到一个脏读。)

NOLOCK在您添加它的查询中没有发出行锁,并且对其他正在运行的查询发出的锁没有影响。 NOLOCK确实发出了一个Sch-S锁,Schema Stability锁,它不会给你带来麻烦。

答案 1 :(得分:3)

我相信你误解了。 select ... with(nolock)将获取任何锁定。也就是说,它不会阻止任何其他写入。

缺点似乎是它将包括未提交的读取,因此结果可能无法保持写入事务回滚。

答案 2 :(得分:3)

只要你不介意从你的桌子上读取脏东西,这对你来说应该不是问题。确保正确设置了转换隔离级别,并且您的调用代码(如果适用)未使用隐式事务,您应该没问题。

微软的交易隔离文件: http://msdn.microsoft.com/en-us/library/ms173763.aspx

NOLOCK是一种常见的,在我看来,在遇到这种情况时会滥用选项。虽然它可以帮助您克服高争用情况下的问题,但它也可能导致难以追踪错误。虽然这是一个持续不断的争论,但请查看http://blogs.msdn.com/b/davidlean/archive/2009/04/06/sql-server-nolock-hint-other-poor-ideas.aspx,了解使用此类提示时的一些风险。

答案 3 :(得分:1)

您可以使用NOLOCK,但我建议您在知道“脏数据”可接受的情况下(例如,您知道数据在插入后永远不会被更改或删除的系统日志数据库)。最好的方法是从未被锁定的数据中选择;你能识别出不受插入影响的行吗?例如,如果插入的数据是CreateDate列默认为GETDATE(),请确保您的查询从该点之前提取数据。

当然,这完全取决于正在写入的数据量以及insert语句是否生成行或页或表锁...

答案 4 :(得分:0)

此处未讨论的一个选项是使用复制。如果复制有问题的表并在复制的数据库上运行查询,则不会阻止插入/更新。 (在您的情况下,我会使用事务复制 - https://msdn.microsoft.com/en-us/library/ms151176.aspx)。