【问题标题】:If I'm updating a DataRow, do I lock the entire DataTable or just the DataRow?如果我要更新 DataRow,我是锁定整个 DataTable 还是只锁定 DataRow?
【发布时间】:2010-04-09 13:10:55
【问题描述】:

假设我从多个线程访问DataTable。如果我想访问特定的行,我怀疑我需要锁定该操作(我可能会弄错,但至少我知道这样我是安全的):

// this is a strongly-typed table
OrdersRow row = null;
lock (orderTable.Rows.SyncRoot) {
    row = orderTable.FindByOrderId(myOrderId);
}

但是,如果我想更新该行,我应该锁定表(或者更确切地说,表的Rows.SyncRoot 对象)再次,或者我可以简单地锁定行?

【问题讨论】:

    标签: c# .net datatable thread-safety datarow


    【解决方案1】:

    实际上,仅在 DataTable 或 DataRow 的一个位置执行lock 实际上并没有任何事情。使用Monitor 锁(lock 块是什么)要记住的一个重要方面是锁定一个对象不会对它做任何事情。这就是一些人提倡使用专用锁定对象而不是锁定资源本身的原因之一,因为它迫使您意识到在处理资源时必须执行锁定(并且在同一个对象上)。

    话虽如此,最好锁定整个DataTable,因为数据存储本身就在那里(DataRow 对象内部仅包含DataTable 的偏移量,用于检索数据的位置) .因此,即使您同步访问各个行,同时更新两个不同行也会导致您以非同步方式更新相同的数据存储机制。

    在将内部类型视为“黑匣子”和只锁定您需要的内容(在这种情况下,这会导致您得出只锁定行的错误结论)和试图深入了解类型的内部工作原理并依赖于实现细节可能会改变

    结果是,现在,你应该锁定整个DataTable,以避免以非同步方式更新内部数据存储系统

    【讨论】:

    • 非常有见地的答案,我明白为什么你觉得有必要指出lock 机制的工作原理......我确实意识到锁定对没有任何作用一个东西;我想我可以用一种更好的方式来表达我的问题是“我需要按行或按表同步更新操作吗?”无论如何,此时我很清楚,我必须同步更新到整个表中的 any 行——无论是通过锁定表还是专用的“表锁”(在这种情况下,我认为Rows.SyncRoot 对象实际上很好地满足了这个目的)。
    【解决方案2】:

    您不需要为读取锁定 - 只为写入/更新。锁定尽可能少的数量,以确保数据一致性......通常只是您正在更新的一行。如果要更新表之间的父/子关系,则需要锁定每个表中的每一行。

    【讨论】:

    • Kevin (social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/…) 提供的链接似乎确实表明锁定表是必要的,实际上。 MSFT 代表说:“假设更新单行不会影响表中的任何其他内容是很危险的,因为您依赖的是可能在以后很容易被破坏的实现细节。”您对这是否属实有任何见解吗?
    【解决方案3】:

    数据表只对多线程读取操作是安全的:

    http://msdn.microsoft.com/en-us/library/system.data.datatable.aspx

    http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/11b69e1a-ad6c-48d5-8e14-264af5b0692e

    在阅读有关数据表的信息时,关于锁定表和允许您安全地连续更新数据的能力存在冲突的信息。根据第二个链接,您可以锁定表并更新行。由于这是来自 MS MVP,我会说您可能可以锁定表并没问题。

    【讨论】:

    • 链接说:“这种类型对于多线程读操作是安全的。你必须同步任何写操作”这不是说锁是多线程访问的正确做法吗?
    • 我很困惑;您提供的第一个链接似乎说您只需要锁定写入(尽管它没有说要锁定 what)。第二个似乎表明锁定表是正确的方法。两者似乎都不同意您的说法,即您不能锁定表并期望读取是一致的。我错过了什么吗?
    • 我的第一句话是不正确的。我发现了相互矛盾的信息。您不需要锁定表来读取数据,因为这没关系。写数据需要锁表。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-06
    • 2011-07-23
    • 2012-11-15
    • 1970-01-01
    • 2016-07-26
    • 2011-12-23
    • 1970-01-01
    相关资源
    最近更新 更多