看來你正在嘗試開發一個隊列。 Wihin SQL服務器,存在用於這樣的場景中的兩個主要的解決方案:
[1] Service Broker(參見:激活,RECEIVE TOP(1)/TOP(100)
)
或
[2]使用表加上UPDATE/DELETE/SELECT TOP(100) ... FROM dbo.QueueTable WITH(READPAST, ROWLOCK)
開發一個定製的隊列。這些表提示的作用如下:
您可以Remus的博客文章在這裏中找到更多詳細信息:http://rusanu.com/2010/03/26/using-tables-as-queues/從表中讀取和處理記錄
一個模板 - 隊列可能是:
SET XACT_ABORT ON
BEGIN TRY
-- BEGIN TRAN
CREATE TABLE #SelectedRecords TABLE (
...
)
DELETE TOP(100) FROM dbo.QueueTable WITH(READPAST, ROWLOCK)
OUTPUT deleted.Col1, deleted.Col2, ... INTO #SelectedRecords (Col1, Cold2, ...);
... Do something with those 100 records ...
-- COMMIT
END TRY
BEGIN CATCH
-- IF @@TRANCOUNT > 0
-- BEGIN
-- ROLLBACK
-- END
END CATCH
如果註釋行是聯合國評論說,SQL Server將在從隊列表讀取數據期間以及在數據處理期間使用一個TX。如果一個異常被catch塊攔截,那麼SQL Server將回滾當前TX(包括那些從隊列表中讀取和刪除的100條記錄)。
注意:理想情況下,數據處理塊不應該打開/創建另一個/嵌套的TX。
注2:你應該檢查是否索引(或堆結構)上隊列表支持定義(或不)從而行鎖:
SELECT i.allow_row_locks, *
FROM sys.indexes i
WHERE i.object_id = OBJECT_ID('dbo.QueueTable')
說明#3:如果allow_row_locks
位爲假/ 0,那麼你可以改變它使用
ALTER INDEX index_name
ON dbo.QueueTable
REBUILD
WITH allow_row_locks = ON
如果鎖定列是足夠的解決方案,唯一的問題是潛在的崩潰只是添加一個主開鎖計劃任務運行在深夜。 – SunKnight0
http://blog.sqlauthority.com/2012/11/15/sql-server-concurrency-basics-guest-post-by-vinod-kumar/ –
http://stackoverflow.com/questions/1138026/sql-服務器性能與多個併發長時間運行查詢 –