有這么一個表,表里有100多萬條記錄,
表名:HorseInfo
ID
userID
Num
CreateTime
運行情況:
1:這個表,有上百萬條資料,而且同時有新資料在插入;
2:同時有1000多個終端,每一個終端讀取一個最新的記錄,讀到之后就立即洗掉掉這個記錄,以便保證每一個記錄,只能被一個終端讀取到。
如果只是用select top 1 ID,userID,Num from HorseInfo where userID=1 order by ID desc,讀到之后再執行洗掉的話,那么就非常容易早場多個終端同時讀到同一個ID的記錄。
為了避免一個記錄只能被一個終端讀取到,如何撰寫sql陳述句,效率最高,且不影響新資料的插入,防止行程鎖死等等問題。
uj5u.com熱心網友回復:
多用觸發器考慮,增加兩個欄位 updateclient 更新的客戶端ID owerclient 歸屬客戶端ID1 客戶端讀取完成后立刻發送UPDATE 陳述句 更新 updateclient ,updateclient 欄位更新的觸發器開始作業,如果owerclient 為null就講updateclient 內容更新到 owerclient ,否則就不更新,這樣第一個更新 updateclient 的就是這條記錄的所有者,可能是并發的很多,但是其他的更新只是 updateclient ,owerclient 一旦更新就永遠是第一個
2 關于洗掉,owerclient 不為空的就可以洗掉了,用觸發器或者計劃任務都可以實作
3 也可以select 的時候 owerclient 不為空就表示為不可用記錄,再后面洗掉也可以,100W記錄也不是很多。
uj5u.com熱心網友回復:
切記:觸發器屬于最后一招, 有其它辦法,不到最后關頭不能使用。1、加個索引,
create index ix_HorseInfo_userId on HorseInfo(userId, id desc);
2、讀取和洗掉用一個事務。
BEGIN TRY
BEGIN TRAN
DECLARE @id INT
SELECT TOP 1 @id=id from HorseInfo WITH(ROWLOCK,XLOCK) where userID=1 order by ID DESC
SELECT * FROM HorseInfo WHERE id=@id
DELETE FROM HorseInfo WHERE id=@id
COMMIT TRAN
END TRY
BEGIN CATCH
ROLLBACK TRAN;
DECLARE @errMsg NVARCHAR(500)
SELECT @errMsg=ERROR_MESSAGE();
RAISERROR (@errMsg , 16 , 1);
END CATCH
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/47984.html
標籤:疑難問題
上一篇:安卓8.0
