我有15个表被标准化为包含记录,许多用户可能在这些表中插入/更新数据(没有两个用户可以同时更新相同的记录,这受到客户端实现的限制)。这15个表在存储过程中逐个更新。WITH(NOLOCK)用于select语句以避免读取锁,因为某些用户可能同时查看数据。但有时这些过程中的select语句会被锁定。作为我过去的经验,我把这些袜子,以避免阻塞。
我不确定WITH(NOLOCK)是否在某个地方丢失了,或者这是另一个问题。Should I search for missing WITH(NOLOCK)?
or what other ways are there to avoid this locking?
与NOLOCK的限制是什么?我只是在读取数据,我不在乎是否读取已提交或未提交的数据。还可以采取哪些其他步骤来删除这个阻塞呢?
发布于 2015-12-23 11:43:05
WITH(NOLOCK) :
WITH (NOLOCK)相当于使用READ UNCOMMITED作为事务隔离级别。
基本上它给出了脏兮兮的读数。也就是说,如果任何事务持有一些数据,然后我们尝试获取数据,它将在事务提交不等待的情况下给出输出。这样我们就不用等待就能读到脏兮兮的东西。
因此,您有可能读取随后回滚的未提交行,即从未将其放入数据库的数据。因此,虽然它可以防止其他操作导致读取陷入僵局,但同时也带来了风险。在高交易率的银行应用程序中,它可能不是解决任何问题的正确方法。
发布于 2015-12-23 13:30:56
当您使用未提交的数据时,可以使用(NOLOCK)。
它会给您带来严重的性能提升,因为您的查询不会等待任何未提交的事务完成。这是一个很好的工具,但必须小心使用,否则,在您负担不起的情况下,您将得到未提交的数据。
发布于 2015-12-23 15:56:57
我认为,根据您在原始帖子上留下的评论,您想要做的是将隔离级别设置为“未注释”。这与无锁相同,只是它在整个事务上设置,而不是在单个select语句上设置。
代码示例:
USE DatabaseName;
GO
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITED;
GO
BEGIN TRANSACTION;
GO
...
COMMIT TRANSACTION;
GO这将防止读取数据库的任何锁。然而,这也将适用于插入,这可能会带来一个可能的并发问题,我可以想象。数据可能会在插入时发生变化。
如果您计划在此隔离级别下对数据库进行更新,我将重新考虑这一点。
下面是ms sql隔离级别的更详细信息:https://msdn.microsoft.com/en-za/library/ms173763.aspx
https://stackoverflow.com/questions/34433613
复制相似问题