2017-10-18 9 views
0

私はユーザが同時にデータを挿入するテーブルCOMMANDSを持っています。書き込みのためのテーブルロックではあるが、読み込みを許可する

すべての挿入後、私は計算に時間を費やし、別のテーブルに結果を保存する必要がありますRESULTS

同時に、すべてのユーザーもCOMMANDSからデータを読み取ります。

私の質問は:新しい$command挿入した後

、私は私の計算では、そのテーブルのすべての行を使用します。すべての行が計算に影響し、現在の計算が行われ結果が保存されるまで、このテーブルを新しい挿入用にロックしたいので、前の$commandsに影響する可能性があります。しかし、私は他のユーザーが現在の状態であるCOMMANDSを見るのをブロックしたくありません。

まもなく読書用にロックせずに書込み用のテーブルをロックしたいと思います。

私はInnoDBエンジンを使用しています。私はロックに関するいくつかの文書を読んでいますが、私は完全に混乱しています。それは愚かなようだが、現在、私は私がより良いと巧妙な解決策が存在する必要があります知っている

public function storeNewCommand($command){ 

    // $busy_flag is an app level global that can be read by all user sessions 

    if($busy_flag){ 
     usleep(10000); 
     return $this->storeNewCommand($command); 
    } 

    $busy_flag = true; //(lock) 

    /* 
    ...insert new $command to COMMANDS 

    ...do calculations using all comands including last one 

    ...store results in RESULTS 
    */ 

    $busy_flag = false; //(unlock) 

} 

下のようなメカニズムを使用しています

共有ロックと排他ロック、意図ロック、ギャップロック...これはループなしで眠ります。しかし、私はどちらを使うのか分かりません。

+0

「ユーザー入力プロセス」を「DBプロセスに保存」から分離し、計算中に新しい行の挿入を回避する方法を制御できるように、キューの設定方法を調べてください。 – Alfabravo

+0

ありがとうございます@Alfabravo私はいくつかのキュージョブを使用していますが、それらは非同期で動作し、すべての挿入後にすべての保存されたコマンドの現在の状態を私にとって非常に重要です。だから、私は、ongoning計算がある場合、データベースレベルでの挿入をブロックしたいと思います。 – Jaxovee

+0

私にとっては、テーブルレベルのロックをエミュレートするのは間違った戦略です。どのように人のユーザーに関係なく、彼らはすべて同じキューと同じDAOを介して要求を送信する必要があります。 – Alfabravo

答えて

1

長さがlock_wait_timeout(デフォルトは50秒)未満の場合、BEGIN ... COMMITを使用してください。 (個人的には、私は50秒ではなく、2秒のように制限します)

そうでなければ、ライターのすべてのテーブルに、この「重要」セクション"。 1行の1列または2列のテーブルよりはるかに多くなる必要はありません。

このミューテックスを取得するときは、必ずトランザクション内でfetch、setなどをカプセル化し、失敗に反応してください。ロックを取得した後、遅いものを続行します。最後にロックを解除します。

注意:クラッシュやソフトウェアのバグがある場合、ロックを解除するコードは実行されない可能性があります。したがって、タイムスタンプと、ミューテックスが「長い時間」にリリースされていないことに気付くようなものを含めるとよいでしょう。彼らは問題についてあなたに電子メールを送り、ロックを解除することができます。

関連する問題