NOLOCK与多线程

时间:2012-01-09 19:10:57

标签: .net sql sql-server multithreading tsql

我正在研究多线程应用程序(C#),并且2个线程同时使用NOLOCK更新表,这是一个问题吗?更具体地说,他们都在更新相同的记录。

4 个答案:

答案 0 :(得分:4)

答案是“它取决于”。

NOLOCK允许'脏读'。这意味着事务中的 ,您可能会看到来自另一个事务的未提交数据。如果您有多个线程更新同一个表中的同一行,您可能会在该线程提交它的事务之前看到另一个线程触及的数据的修改值。

例如,取表account_balances,定义为(account_num int,balance decimal(12,2))。让我们假设发生以下情况:

//前提条件,帐户#1的余额为10.00

  1. 线程#1启动一个事务,将帐户#1递减10
  2. 线程#2启动一个事务,尝试读取帐户#1的余额。它的余额为0。
  3. 线程#2将帐户减少5美元,并向客户发出透支(其余额为-5)
  4. 线程#1回滚它的交易
  5. 线程#2提交它的交易
  6. //帐户余额现在为-5,即使它应为5。

    不会看到的是某个字段中某种形式的不一致数据 - nolock提示与运行没有锁定的多线程代码不同 - 个别写入仍然是原子的。

答案 1 :(得分:2)

这意味着您可以获得处于“错误”状态的记录。

例如......

  • Process1正在删除数据块
  • Process2正在读取重叠的数据块,WITH NOLOCK

在理想情况下,Process1删除的所有记录都存在或被删除。因为Process2正在使用NOLOCK,所以它可能会读取Process1正在删除的记录的 某些 ,而不会读取其他记录,因为它们已经消失了。

INSERTS和UPDATES也是如此。您可以简单地阅读仅通过某种方式进行更改的部分记录。


这是否是一个问题取决于您的数据,您的设计等。

搜索引擎不会在意这是否发生。处理财务交易的银行将会。

答案 2 :(得分:0)

即使使用NOLOCK提示,也无法同时更改同一记录。

<强> BUT

您可以将数据置于不一致状态。

AFAIK - 无法将此提示应用于目标更新表。

并且 - 此提示允许您读取未提交的数据,不会覆盖

答案 3 :(得分:0)

小心你如何使用它。潜在的数据不一致。

如果有一个查询      使用(nolock)从tableA设置colA =“newColANewvalue”,其中colA =“colAOldvalue”

另一个问题是      使用(nolock)从tableA设置colC =“colCnewValue”,其中colA =“colAOldvalue”

您最终可以在同一记录中使用colC =“colCnewValue”和colA =“newColANewvalue”。如果那不是问题,那就OK。

是什么驱使这个?您是否遇到了rowlock或pagelock的性能问题?

相关问题