2016-08-02 41 views
0

我試圖在多個任務中執行存儲過程,但它可能是從緩存中提供數據。讀取線程中的數據返回相同的記錄

這裏是我的代碼:

var entities = new PhonePushEntities(); 
var lst = Task.Run(() => entities.GetInAppAlertBatch("ios", DataPacketSize).ToList()); 

此代碼也在父任務運行。

存儲過程:

ALTER PROCEDURE [dbo].[GetInAppAlertBatch] 
    @DeviceType as varchar(10), 
    @PSize as int 
AS 
BEGIN 
    SET NOCOUNT ON; 

    begin tran InApp_Fetch_Process 
    declare @t as TABLE (id int) 

    insert into @t 
    SELECT top (@PSize) sKey FROM InAppAlerts 
    where JobStatus = 'pending' AND DeviceType = @DeviceType 

    UPDATE InAppAlerts 
    SET JobStatus = 'inprocess' 
    where sKey in (SELECT id from @t) 

    select * from InAppAlerts where sKey in (select id from @t) 

    COMMIT TRAN InApp_Fetch_Process 
END 

我的問題是邏輯:如果我們看到存儲過程,那麼每次它應該返回唯一的數據,但它返回了一些線程相同的記錄。

+0

又有什麼問題?或者有什麼問題?你需要什麼幫助? –

+0

@DawidFerenczy,邏輯上,如果我們看到SP,那麼每次它應該給出唯一的數據,但是給某些線程提供了相同的記錄。 – imlim

+0

你是說,同時運行* N *個線程/任務會導致每個都獲得相同的結果嗎?考慮到你的結構,它*會有意義。您的交易將阻止更新,但基本上會更新相同的記錄列表。 –

回答

0

如果你的問題是多個併發線程或任務返回相同的結果,你可以通過不先選擇記錄來解決它。選擇語句不會彼此阻塞。

我會推薦的是,您使用唯一標識符更新事務中所需的記錄,然後選擇這些記錄。既然你會唯一標記一些記錄你應該沒問題。儘管如此,你仍然需要一個新的列。嘗試是這樣的(未經測試):

ALTER PROCEDURE [dbo].[GetInAppAlertBatch] 
    @DeviceType as varchar(10), 
    @PSize as int 
AS 
BEGIN 
    SET NOCOUNT ON; 

    begin transaction 

    declare @guid uniqueidentifier = newid() 

    update top (@PSize) InAppAlerts set padlock = @guid 
    where JobStatus = 'pending' and DeviceType = @DeviceType 

    select * from InAppAlerts where padlock = @guid 

    commit 
END 

如果需要訂購上看看馬丁史密斯回答:how can I Update top 100 records in sql server

+0

當2個線程同時嘗試讀取記錄時,這成爲死鎖 – imlim

+0

這有點奇怪。是否還有其他訪問可能會干擾的相同數據? –

+0

你是否設法讓它工作? –

相關問題