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

:この(未テスト)のようなものを試してみてくださいhow can I Update top 100 records in sql server

+0

これは、2スレッドが同じ時刻にレコードを読み取ろうとしたときにデッドロックになる – imlim

+0

これはやや奇妙です。おそらく干渉する同じデータにアクセスする他のものはありますか? –

+0

あなたはそれを動作させることができましたか? –

関連する問題