2016-08-02 2 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

Если ваша проблема в том, что несколько параллельных потоков или задач возвращают те же результаты, вы можете решить эту проблему, не выбрав сначала записи. Операторы Select не блокируют друг друга.

Что я рекомендую, так это то, что вы обновляете необходимые записи в транзакции с помощью уникального идентификатора и затем выбираете их. Поскольку вы будете однозначно отмечать некоторые записи, вы должны быть в порядке. Для этого вам понадобится новый столбец. Попробуйте что-то вроде этого (непроверенные):

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 

Если вам нужно приказывать на что взглянуть на Мартина Smiths ответ: how can I Update top 100 records in sql server

+0

Это становится мертвой блокировкой, когда 2 потока пытаются прочитать запись в то же время – imlim

+0

Это несколько странно. Есть ли что-нибудь еще для доступа к тем же данным, которые могут мешать? –

+0

Вам удалось заставить его работать? –