2011-10-12 11 views
6

例えば、私は列C1 value = 'clean'と行を持って、2つの異なるクライアントが同時にでこのクエリを実行します。トランザクションを使用しないMyISAMとInnoDBでは単一のmysql文がアトミックなのでしょうか?

update T1 set C1 = 'dirty' where Id = 1 

、それは関わらず、エンジンタイプのことが保証されていますmysql_affected_rows()の値は、1クライアントの場合は1、もう一方のクライアントの場合は0となります。

+1

アトミック性は必要ですが、InnoDBテーブルを使用したくない場合は[MySQLロックテーブルを参照してください](http://dev.mysql.com/doc/refman/5.1/en/lock-tables。html) – bobobobo

答えて

11

はいとはありません:-)どちらの場合も

access is serialised彼らは同じ行を打つので、(あなたはInnoDBのようなトランザクションエンジンを使用していると仮定した場合)ので、彼らがお互いに干渉することはありません。言い換えれば、文アトミックです。

ただし、影響を受ける行数は実際に接続を開いたときの構成設定によって異なります。 page for mysql_affected_rows()はこれが(私の太字)と言うことがあります。

UPDATE文、影響を受けた-列値の場合、デフォルトでは、実際にを変更された行の数です。 mysqldに接続するときにmysql_real_connect()にCLIENT_FOUND_ROWSフラグを指定すると、影響を受けた行の値は行の数になります"found";つまり、WHERE句でマッチします。

そしてthe mysql_real_connect pageから:

CLIENT_FOUND_ROWS:の数を返しますが(マッチ)行、ない変更行の数を発見しました。データはは、だけ何行に変更されたかどうか

UPDATE T1 SET C1 = 'dirty' WHERE id = 1 

がで行うにはを持っていない:CLIENT_FOUND_ROWSを何が起こるかという点でそう

は、影響を受けた行に対して、設定されていますが一致しました。これは両方のクエリで1になります。 CLIENT_FOUND_ROWSない設定された場合

一方、2番目のクエリは、(それがすでに「ダーティ」でポピュレートだから)、実際に行を変更されず、ゼロの行数を有することになります。あなたはInnoDBのようなトランザクションストレージエンジンを使用している場合

UPDATE T1 SET C1 = 'dirty' WHERE id = 1 AND C1 <> 'dirty' 
+0

MyIASMでは、単一ステートメントの更新はアトミックではないと言いますか? – Pacerier

+0

速いgoogleは、あなたがスレッドやクエリをkillすることがない限り、MyISAMはほとんどがアトミックであることを示唆しています。 http://bugs.mysql.com/bug.php?id=51193 –

+0

@サンマイ:http://dev.mysql.com/doc/refman/5.5/en/innodb-locks-set.htmlより:ロックUPDATE、またはDELETE一般的に設定されたレコードは、SQLステートメントの処理でスキャンされるすべての索引レコードにロックされます。 – paxdiablo

3

MySQLはACID準拠です:あなたは関係なく、その設定(のみ示す変化)の同じ行動を望んでいた場合

、あなたのようなものを使用することができます。

関連する問題