2012-04-16 20 views
1

は、関数は次の構造を有する:MySQLのMyISAMの競合状態

$q = 'LOCK TABLES table1 WRITE;'; 
mysql_query($q);  
$q = 'select id from table1 where is_delete = 0 limit 1;'; 
$res = mysql_fetch_assoc(mysql_query($q)); 
if($res) { 
$q = 'UPDATE table1 SET is_delete = 1 WHERE id = '".$res['id']."''; 
mysql_query($q); 
} 
$q = 'UNLOCK TABLES;'; 
mysql_query($q); 

私はすべてのテーブルをロックしますが、クエリは、並列に実行します。 これをどのように修正しますか?あなたがLOCK TABLESをクエリに任意のMySQLのエラーを取得しているかどうかを

+1

テーブルをロックするコードはどこですか? –

+0

申し訳ありませんが、質問は更新されました – Merlin

+0

あなたのユーザーはLOCK TABLES権限を持っていますか? – angrychimp

答えて

0

チェック:これは、あなたがやっているすべてある場合

$q = 'LOCK TABLES table1 WRITE'; 
$r = mysql_query($q) or die(mysql_error());  

しかし、あなたはまた、単に書くことができます。

UPDATE `table1 SET `is_delete` = 1 WHERE `is_delete` = 0 LIMIT 1 

は全くロックを必要としません。もちろん、これは最初のクエリのデータが何らかの方法で処理されておらず、is_deleteが0に設定されている限り、更新する行が実際に問題でない場合にのみ機能します。あなたが投稿したコードもありますが、このコードをどのように使用するのかはすぐわかりません:)

もっと一般的には、MySQLテーブル用にデフォルトのInnoDBストレージエンジンを使用している場合、 SELECT ... FOR UPDATEに見てみたいことがあります。 http://dev.mysql.com/doc/refman/5.0/en/innodb-locking-reads.html

あなたが書くことができます:

$q = 'select id from table1 where is_delete = 0 limit 1 for update'; 
$res = mysql_fetch_assoc(mysql_query($q)); 

if($res) { 
    $q = 'UPDATE table1 SET is_delete = 1 WHERE id = '".$res['id']."''; 
    mysql_query($q); 
} 

も参照してください:http://www.mysqlperformanceblog.com/2006/08/06/select-lock-in-share-mode-and-for-update/

+0

ここでははるかに複雑です – Merlin

+0

もちろん、あなたは私たちに、もちろん動作していない特定のコードを表示する必要があります。 – Daan

+0

私のストレージエンジンはmyisamです。この場合はロックテーブルが必要です。しかし、助けてはいけない( – Merlin

関連する問題