2017-01-08 11 views
0

私たちはMySQL InnoDBを使用しています。同時に発生する複数の要求をサポートします。 ここでは、達成しようとしているものの簡略化した例を示します。 電球を表すエンティティを保持するテーブルがあるとします。これらの電球は、ユーザによってオン(作動)することができる。ユーザーはテーブルに電球を追加することができます。電球は最初は無効化されており、そのうち10個だけが有効化としてマークされます。MySQL InnoDBの競合状態を回避する方法は?

セッション1:

1:だから我々は、システムが同時実行をサポートしているので、10の制限は、次の例に基づいて、競合状態の危険がある持っているアクティブな電球の数を取得

2:起動した電球の数を確認してください

3:制限に達していない場合は、電球を作動させて確定してください。

4:そうでなければロールバックします。

ここで問題となるのは、ステップ2と4の間に別のセッションが入る可能性があり、上限を超えてしまう可能性があるということです。

は、これは私たちが現在何をしているかのSQL表現である:

  1. SELECT COUNT(ID)TBLからの総AS WHERE 1 = is_active。
  2. if(合計< 10){
  3. 別の球を活性化する。 } else {
  4. ロールバック; }

このシナリオでは、どのような解決策をお勧めしますか? 「選択更新」を検討していましたが、誤解がなければ選択した行をロックし、選択した行がロックされている間にユーザーがテーブルに電球を追加できます。

ありがとうございます。行があなたは制限が満たされている知っている更新しない場合

update active_bulb_count 
    set active_count = active_count + 1 
    where active_count < limit 
     and <any other conditions needed>; 

+0

電球を「アクティブにする」必要がありますか、まったく何もしませんか?彼はもはや「活性化」できないことをユーザーに知らせることに注意してください。 (私は問題の声明が不完全であると感じています。) –

答えて

0

ひとつのアイデアは、あなたがこの制限の要件を管理する別のロックテーブルを保つなど、アクティブ電球の数にのみアトミック更新を行うことです、あなたは電球をアクティブに設定しませんでした。

この操作を実行するセッションのトランザクション設定は、おそらく考えられます。より多くのアトミックアップデートの詳細と取引MySQL Atomic UPDATE in InnoDB vs MyISAM

+0

あなたの提案に似た何かをやめました。 1つの行テーブルを保護者として働き、すべてのリソースアクセスをシリアライズするmutexとして使用しています。あなたの助言と@Rick Jamesの指導に感謝します。皆さん、ありがとうございました。 –

+0

@JinIzzraeel - 単一行のミューテックス表には、通常、プライマリ・キーをロックするための1つと、ステータスのための1つ(ロックと誰がロックしているかの指標)の2つの列が必要です。あなたが好きなら、新しい質問を_あなたの詳細で始めてください。彼らは十分に異なっている可能性が高い。 –

+0

@Rick Jamesあなたの返事を感謝します。シングルブロックミューテックスは保護者として機能し、すべてのリソースへのアクセスをシリアライズします。これは、コードブロックがすべての要求に対する単一のアクセスポイントであるためです。私の理解では、それは私たちの場合には十分であるはずです。ありがとうございました。 –

0
BEGIN; -- start a "transaction" 
do the 4 steps 
COMMIT; -- or ROLLBACK 

を参照してください。注:UPDATEにつながる可能性がどれSELECTsFOR UPDATEを言う必要があります。

UPDATEでもっと仕事をする方法を見てください(churdの答えを参照)。またはINSERT ... ON DUPLICATE KEY UPDATE ...

INSERTおよびUPDATEは、影響を受ける行の数を報告できます。これは、「タスクが成功すると想定する」ために使用され、失敗した場合にはそれをチェックし、失敗した場合には回避行動をとることができます。

関連する問題