2012-05-14 20 views
6

mysqlのコミットとトランザクションに関する質問があります。mysqlのコミットとトランザクション

私はmysqlクエリを実行するいくつかのPHP文を持っています。

私は次のように言いますか?

mysql_query("START TRANSACTION"); 
//more queries here 
mysql_query("COMMIT"); 

これは正確には何ですか?どのように役立ちますか?更新については、削除および挿入私はまた、これは読書から他のクエリをブロックすることが分かっ:

mysql_query("LOCK TABLES t1 WRITE, t2 WRITE"); 
//more queries here 
mysql_query("UNLOCK TABLES t1, t2"); 

は/選択を書き込み、どんな性質又はこのブロックだけが他のクエリのでしょうか?

もう1つの質問:1つのクエリが実行中で、他のクエリをブロックしているとします。別のクエリがブロックされたデータにアクセスしようとしました。ブロックされたデータが表示されます。それはどのように進んでいますか?データが再びブロック解除され、クエリを再実行するまで待機しますか?それはちょうど失敗し、繰り返される必要がありますか?もしそうなら、どうすれば確認できますか?

ありがとうございます!あなたが「オン」で自動コミットのデフォルト設定を変更していない場合

InnoDB内でデニス

+0

InnoDBまたはMyISAMテーブルを使用していますか? – Daan

+0

@ダーン私はInnoDBを使用して – weltschmerz

答えて

12

は、明示的に、単一のクエリに開始または終了取引する必要はありません。自動コミットがオンの場合、InnoDBはトランザクション内のすべての単一SQLクエリを自動的に囲みます。これはSTART TRANSACTION; query; COMMIT;に相当します。

自動コミットを有効にしてInnoDBでSTART TRANSACTIONを明示的に使用すると、START TRANSACTION文の後に実行されるクエリはすべて実行されるか、すべてが失敗します。これは銀行環境で便利です。たとえば、500ドルを銀行口座に振り替える場合、その金額が銀行の残高から差し引かれて自分の口座に加算された場合にのみ、その操作が成功するはずです。したがって、この場合は、次のように実行します。

START TRANSACTION; 
UPDATE customers SET balance = balance - 500 WHERE customer = 'Daan'; 
UPDATE customers SET balance = balance + 500 WHERE customer = 'Dennis'; 
COMMIT; 

これにより、両方のクエリが正常に実行されるか、存在しないかが保証されます。 This postには、トランザクションを使用する必要がある場合があります。

InnoDBでは、ほとんどの場合、テーブル全体をロックする必要はほとんどありません。 InnoDBは、MyISAMと異なり、行レベルのロックをサポートします。つまり、クライアントはテーブル全体をロックする必要がなく、他のクライアントを待たせる必要があります。クライアントは実際に必要な行だけをロックし、他のクライアントが必要な行にアクセスし続けるようにする必要があります。

InnoDBトランザクションの詳細については、hereを参照してください。デッドロックに関するご質問は、14.2.8.814.2.8.9のセクションで回答しています。クエリが失敗した場合、MySQLドライバはその理由を示すエラーメッセージを返します。必要に応じて、アプリはクエリを再発行する必要があります。

最後に、コード例では、mysql_queryを使用しました。新しいコードを書いている場合は、古くて遅く、廃止予定のPHP用のmysql_ライブラリを使用せず、mysqli_またはPDOを代わりに使用してください:)

+0

素晴らしい、ありがとう! InnoDBは自動的に行をロックするだけですか?そして、私のテーブルに自動コミットがあるかどうかをどうやって確認できますか?(私はphpmyadminを使用しています) – weltschmerz

+0

あなたは 'SHOW VARIABLES LIKE 'autocommit'クエリを発行するか、phpMyAdminホームページで' variables'をクリックすることができます。インデックスを作成するには、適切なデータベースとテーブルに移動し、 'structure'をクリックしてそこに表示されているフォームを使用してインデックスを作成します。あるいは、SQL文を発行することもできます。 'ALTER TABLEテーブルADD INDEX(フィールド)'。 「InnoBDは自動的に行をロックするだけです」という意味は分かりません。つまり、それが意味するものであれば、テーブル全体を自動的にロックすることはありません:) – Daan

+0

自動コミットはありますか?主キーは常にインデックスとして機能しますか?私のテーブルにプライマリキーがあり、インデックスを追加したいのですが、プライマリキーと同じでなければならないと言いました... – weltschmerz

関連する問題