2009-05-31 9 views
0

私は、グループの人がデータ入力タスクのキューを操作できるようにする効率的な方法を考えようとしています。これまでは1人でこれをやっていたので問題はありませんでした。バックエンドはRDBMSで、フロントエンドはWebアプリケーションです。複数の同時ウェブアプリケーションユーザーにデータ入力タスクを割り当てる

現在、我々はこのような何か:

UPDATE records SET ..., in_edit_queue = false 
    WHERE id = ? AND in_edit_queue = true; 
:以前に割り当てられたレコードへの変更を保存するには、次に

SELECT * FROM records WHERE in_edit_queue LIMIT 1; 

:編集用にレコードを割り当てるには

これは、2人のユーザーが同じレコードをediに割り当てることが可能であることを意味しますトン、と私たちは例えば、その後の提出に静かに失敗し、提出する最初のものを好む:

  • ユーザBが提出し編集するための記録321まで
  • ユーザBの負荷を編集するための記録321まで

    1. ユーザAのロード変更
    2. ユーザーAが変更を提出(彼らはDBに保存されます)(彼らはDBに保存されません)

    (注:私たちは、許容可能なデータを提出するすべてのユーザーの皆様に信頼することができますので、必要はありません私たちがデータをthから維持するためにe second )

    この方法の問題は、ユーザーが同じ時間に開始してほぼ同じ速度で編集するときに、同じレコードを更新することが多く、1つしか保存されないことがあります。言い換えれば、多くの工数を浪費しています。ランダム行を選択することでこれをある程度緩和することができますが、私はもう少し保証されたものを好むでしょう。だからここ

    は私が考えているものです...

    と呼ばれるテーブルがある:locked_records (record_id integer, locked_until timestamp)

    -- Assign a record for editing: 
    -- Same as before but also make sure the 
    -- record is not listed in locked_records... 
    SELECT * FROM records 
        WHERE in_edit_queue AND id NOT IN (
        SELECT record_id FROM locked_records 
        WHERE locked_until > now()) 
        LIMIT 1; 
    
    -- ..and effectively remove it from 
    -- the queue for the next 5 minutes 
    INSERT INTO locked_records (record_id, locked_until) 
        VALUES (?, now() + 300); 
    

    その後:

    UPDATE records SET ..., in_edit_queue = false 
        WHERE id = ? AND in_edit_queue = true; 
    DELETE FROM locked_records WHERE record_id = ?; 
    

    典型的な編集は1分に約30秒かかります、キューから5分は良い量でなければなりません。私はまた、有利であることが判明した場合、Webアプリケーション上でXHRをロックを更新し続けることができます。

    誰でもこれについての考えを提供できますか?物事をする良い方法のように聞こえる?恐ろしい方法のような音ですか?これを前に完了しましたか?私はいくつかのフィードバックを聞いてほしいです。

    ありがとうございます! J

  • 答えて

    0

    ロックの内部リストはどうなっていますか? SELECT文をSELECT FOR UPDATEに変更するとオプションになりますか?

    +0

    アップデートはウェブアプリケーションとは異なるデータベース接続を介して行われるため、そうは思わない。私は何かを誤解している場合は私に知らせてください... –

    +0

    p.s.あなたが別のlocked_recordsテーブルを維持する代わりにそれを意味するのであれば、それはうまくいくだろうと思うが、 'レコード'テーブルは常に非編集ユーザによってかなり読み込まれているのでロックしたくないそれはその理由のためです。 –

    +0

    異なるDB接続が使用される可能性は評価する必要があります。あなたは、SELECT FOR UPDATEがそのシナリオではうまくいかないことは間違いありません。 SELECT FOR UPDATEは、ほとんどのRDBMSで読者のアクセスを妨げてはならないので、あなたのドコモをチェックする必要があります。 – Karl

    0

    もう1つのアイデア:これらのレコードには、2つの追加列、assigned_toとcompletedがあります。

    誰かがレコードを編集したいときは、バックその行を取得するには、次に

    update records set assigned_to = ? # assigning to 'me' 
    where assigned_to is null 
    and completed = false 
    limit 1 # only assign one record at a time 
    

    ような何かを:

    select ... 
    from records 
    where assigned_to = ? # assigned to 'me' 
    and completed = false 
    

    そして、あなたが完了真」に設定設定が完了したら'

    レコードが他のユーザーに割り当てられたときに追加のタイムスタンプ列を作成し、上記の更新ステートメントのwhere句の「assigned_to is null」部分にOR代替を追加することができます。割り当てが有効であることを示します。