我正在嘗試運行以下代碼以在并行更新資料庫(使用多個執行緒)時顯示“不一致”,但是當我運行此代碼時,表中的值始終是一致的,即 500。它是如何作業的?
static void Main(string[] args)
for (int i = 0; i < 500; i ) {
Thread t = new Thread(() => Update());
t.Start();
}
await Task.Delay(100000);
}
public static void Update() {
using (var conn = new SqlConnection("mssql-connection-string")) {
conn.Execute("update [table] set counter = counter 1;");
}
}
uj5u.com熱心網友回復:
您擁有的代碼不會導致競爭條件,因為您想要的UPDATE行將被鎖定、遞增,然后釋放鎖;這意味著任何其他UPDATE嘗試同時運行的陳述句都必須“等待”第一個 UPDATE陳述句完成。
如果要模擬競態條件,請先將值分配給變數;這應該給你的行為:
DECLARE @c int = (SELECT counter FROM dbo.[table]); --I assume table only has 1 row
UPDATE dbo.[table] SET Counter = @c 1;
這將意味著 的值counter將首先分配給變數,這不會鎖定該行以防止其他行程讀取它。因此,多個同時執行緒可能都同時讀取該行,然后將其讀取UPDATE到它們各自的 1 值。因此,5 個執行緒可能都將值讀取為7,并將UPDATE值讀取為7 1( 8)。
如果由于某種原因,您確實需要先將表中的值分配給變數UPDATE,然后再將它們分配給變數,那么您需要UPDLOCK在查詢中使用提示:
DECLARE @c int = (SELECT counter FROM dbo.[table] WITH (UPDLOCK)); --I assume table only has 1 row
UPDATE dbo.[table] SET Counter = @c 1;
您可能還需要將事務的隔離級別更改為SERIALIZABLE.
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/475217.html
下一篇:C執行緒不在linux終端中運行
