sql >> データベース >  >> RDS >> Sqlserver

FIFOキューのSQLスレッドセーフUPDATETOP1

    私の懸念は重複する[InvoiceID]
    同じ[InvoiceID]の複数の印刷リクエスト

    最初の更新で、1つの行がset [Status] = 'Printing'を取得します

    2回目の更新で、すべての[InvoiceID]行がset [Status] = 'Printed'になります。
    これにより、status='draft'の行も設定されます

    多分それはあなたが望むものです

    set [Status] = 'Print'の前に、別のプロセスが同じ[InvoiceID]を取得する可能性があります

    そのため、一部の複製は印刷され、一部は印刷されません

    update lockの使用についてコメントします

    これは決定論的ではありませんが、top (1)を取ることができます order byをスキップします 。最新の行を取得する傾向がありますが、それは保証されません。キューをクリアすると、すべてが取得されます。

    これは、「ドラフト」=1

    を失う可能性があることを示しています。
    declare @invID int; 
    declare @T table (iden int identity primary key, invID int, status tinyint);
    insert into @T values (1, 2), (5, 1), (3, 1), (4, 1), (4, 2), (2, 1), (1, 1), (5, 2), (5, 2);
    declare @iden int;
    select * from @t order by iden;
    
    declare @rowcount int = 1; 
    while (@ROWCOUNT > 0)
        begin
            update top (1) t 
            set t.status = 3, @invID = t.invID,  @iden = t.iden
            from @t t 
            where t.status = '2';
            set @rowcount = @@ROWCOUNT;
            if(@rowcount > 0)
                begin 
                    select @invID, @iden;
                    -- do stuff  
                    update t 
                    set t.status = 4
                    from @t t
                    where t.invID = @invID; -- t.iden = @iden;
                    select * from @T order by iden;
                end
        end
    


    1. 無効な日時形式:1292不正な日時値

    2. Mysql:入れ子集合ツリーでのスーパーノードの検索の最適化

    3. 国際文字を使用すると、mysqlクエリから二重の結果が得られます。つまり、Å/Ä=A&Ö=O、

    4. PostgreSQLのシードファイルを使用する場合のJPAの例外