2017-05-03 37 views
2

在我們的Java應用程序內部,我們使用了一個SQL Server語句來暫停某些進程。(UPDLOCK,ROWLOCK)鎖定整個表格甚至只有1行被選中

這是SQL語句:

SELECT * FROM MESSAGES WITH (UPDLOCK, ROWLOCK) 
WHERE MESSAGES.INTERNAL_ID IN ('6f53448f-1c47-4a58-8839-e126e81130f0'); 

從運行過程的IN條款的改變的UUID運行。

爲此,我們使用了鎖定Java代碼:

entityManager.createNativeQuery(sqlString).getResultList() 

上面的SQL語句返回只有一行。不幸的是,整個表似乎都被鎖定了。結果是所有進程都被鎖定,即使沒有或只有一些應該被阻止。

即使指定了UPDLOCK,爲什麼整個表都被鎖定?


其他信息:

  • MESSAGES.INTERNAL_IDNVARCHAR(255)這是不可爲空。 否則對列沒有限制。
  • 隔離級別是READ_COMMITTED
+0

提供'messages'表的定義(ID是主鍵?)什麼是您的事務隔離級別? –

+0

@MikhailLobanov我已將所要求的信息添加到問題中。 –

回答

1

這是因爲您的MESSAGES.INTERNAL_ID不是關鍵。一旦行被鎖定,您無法讀取並檢查其值。嘗試在此列上創建主鍵。

如果這是不可能的,在其上創建INDEX和重寫查詢:

SELECT MESSAGES.INTERNAL_ID FROM MESSAGES WITH (UPDLOCK, ROWLOCK) 
WHERE MESSAGES.INTERNAL_ID IN ('6f53448f-1c47-4a58-8839-e126e81130f0'); 

MSDN說:

鎖提示ROWLOCK,UPDLOCK,和XLOCK是獲取行級鎖 可能鎖定索引鍵而不是實際的數據行。例如,對於 示例,如果一個表具有非聚簇索引,並且使用鎖定提示的SELECT語句 由覆蓋索引處理,則將在覆蓋索引中的索引鍵上獲取鎖 而不是 中的數據行基表。

+0

謝謝!我現在使用主鍵進行鎖定,並且它可以工作。 –

+0

只是另一個問題:'SELECT MESSAGES.ID'是重要的部分還是'WHERE MESSAGES.ID'? –

+0

如果您創建主鍵,這並不重要。 PK通常是一個聚集索引(聚集索引總是覆蓋)。但是如果你要創建一個非羣集索引,你應該小心選擇列表。 –

相關問題