读取线程中的数据返回相同的记录

时间:2016-08-02 13:32:33

标签: c# sql-server stored-procedures task

我正在尝试在多个任务中执行存储过程,但它可能是从缓存中提供数据。

这是我的代码:

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

我的问题是逻辑上的:如果我们看到存储过程,那么每次它应该返回唯一数据,但它会为某些线程返回相同的记录。

1 个答案:

答案 0 :(得分: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

如果您需要订购,请查看Martin Smiths的回答:how can I Update top 100 records in sql server