2009-07-08 3 views
1

私は複数のワーカーを選択して行を更新しています。MYSQL行がUPDATEDを2回以上受け取らないようにするにはどうすればよいですか?

IDステータス 10新しい11新しい 12古い 13古い

ワーカーは、 '新しい' 行を選択し、 '古い' へのステータスを更新します。 2人のワーカーが同じ行を同時に選択するとどうなりますか? 私は、worker1が新しい行を選択し、worker1がそのステータスを更新する前に、worker2が同じ行を選択することを意味しますか?

1つのクエリでSELECTとUPDATEを行う必要がありますか、別の方法がありますか?

答えて

2

読んで前にテーブルをロックし、書いた後にロックを解除することができます。これにより、2人の作業者が同じレコードを同時に更新する機会がなくなります。

http://dev.mysql.com/doc/refman/5.0/en/lock-tables.html

+0

は、SELECT /読書防ぐロックしていますか?私がまだ選択できるのであれば、私はちょうど以下に述べる概念@daremonを使うかもしれない。 –

+1

書き込みロックを行うと、他のすべてのセッションは、読み取りまたは書き込みを試みるとブロックされます。 – Pro777

0

データベースのストレージエンジン(InnoDBは、MyISAMテーブルなど)に応じて、人はそれを・修正している間、テーブルをロックすることができるかもしれません。それは同じ表に類似行動を保持します。

0

あなたは、ロックを暗示するためにあなたのPHPロジックの条件を置くことができますか? 2番目のユーザーが更新を実行できない行にステータス属性を設定する。これは、行がロックされていないことを確認するために更新の前にデータベースを照会する必要があります。

+0

更新の直前にデータベースにクエリを実行すると、並行処理の保護が良好でなくなります。 –

3

あなたはLOCK TABLESを使用することができますが、時々私は(擬似コードで)以下のソリューションを好む:

// get 1 new row 
$sql = "select * from table where status='new' limit 0, 1"; 
$row = mysql_query($sql); 

// update it to old while making sure no one else has done that 
$sql = "update table set status='old' where status='new' and id=row[id]"; 
mysql_query($sql); 

// check 
if (mysql_affected_rows() == 1) 
    // status was changed 
else 
    // failed - someone else did it 
+0

あなたのコードでやったことも私がやったことです。私はそれが最も効率的だとは思わないが、それは簡単であり、それは機能する。ありがとうございました! –

関連する問題