- ベストアンサー
MySQLのトランザクションについて
WEBアプリ上の、MySQLのトランザクションについて質問です。 トランザクションは、データの挿入に矛盾がない場合commitすることによって データの挿入等を確定する機構だとおもいますが、 この仕組みって、トランザクション中は作業対象のテーブルは実行中のクライアント以外 アクセスできなくなる(※つまりロック?がかかっている?)のでしょうか? そうじゃないと、意味がないですよね?やっぱり。。。 また仮にですが、例えばAというクライアントがWEBサイトにアクセス中に Bというクライアントが待ったく 同じ動作を同じタイミングでアクセスした場合ってどうなるのでしょうか? 実際、WEBアプリでそこまでの例外というか処理って行うものでしょうか? また、ちなみにMySQLの場合、 "START TRANSACTION" というSQL文だけでなく AUTOCOMMIT = 0 として、自動コミットをオフにしつつ beginという式で トランザクションを開始する方法があるようですが、実際はどちらの方が当たり前のほうほうなのでしょうか? 識者の方ご教授ください。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
こんにちは。 > この仕組みって、トランザクション中は作業対象のテーブルは実行中のクライ > アント以外アクセスできなくなる(※つまりロック?がかかっている?)のでしょうか? MySQLにおいて、トランザクションが有効になるのはInnoDBエンジンを利用した場合であることはよろしいですよね?最新のバージョンではデフォルトのエンジンがInnoDBになっているので、有効になりますが、以前のMyISAMエンジンでは有効になりません。 で、ロックについてですが、更新中はロックが起きるのは、トランザクションを有効にしているか無効にしているかに関係なくロックされます。 MyISAMの場合はテーブル丸ごとロックし、InnoDBについてはレコード単位でロックします。 ですので、MyISAMの場合、何らかのレコードに更新処理があるときは、ほかのクライアントは更新処理が終了してから処理されます。一方、InnoDBの場合は、更新処理が行われているレコードのみがロックされているため、該当のレコード以外であれば平行して更新処理が行われます。 > 実際、WEBアプリでそこまでの例外というか処理って行うものでしょうか? それをしなくていいのがDBですね。 > 実際はどちらの方が当たり前のほうほうなのでしょうか? 自分の場合は習慣的にSTART TRANSACTIONを使っていますが、好みの問題のような気がします。
その他の回答 (2)
- はせがわ もぐら(@mogura_198)
- ベストアンサー率66% (14/21)
トランザクションについてはACID特性で検索されると良いかもしれません。 ロックについてはテーブルの特性によってロックの種類を変えましょう。 クリティカルな処理は排他ロック(他のトランザクションからは参照も更新もできない)を使うことをお勧めします。 このへんはトランザクション分離レベルで検索すると出ます。 >AUTOCOMMIT = 0 僕は「AUTOCOMMIT = 0 」で運用しています。 一度に複数のテーブルを更新したり、挿入する場合途中でデッドロックしたり、タイムアウトすることがあります。このときAUTOCOMMIT = 1だと中途半端な状態でcommitされてしまいます。 あと気をつけることといえば、暗黙のコミットとというのがあります。 COMMIT流してないのにCOMMITかかったような動作があった場合に参考になると思います
- nora1962
- ベストアンサー率60% (431/717)
MySQLのInnoDBエンジンでは行レベルロックを行います。 テーブル単位のロックではありません。同一行について排他ロックがかかるときは先行トランザクションが終了するまで、後続のトランザクションが待たされます。 「BEGIN」はMySQLでは、「START TRANSACTION」と同義です。出来ればプロジェクトなどでは統一しておいた方がいいと思います。 http://dev.mysql.com/doc/refman/4.1/ja/innodb-transaction-model.html
補足
ご教授ありがとうございます。 更新系のSQLの発行では、実行中のクライアント以外は全て、処理がとまってしまうのですね。 なるほど。 レコード単位のロックというのは、たとえばあるテーブルのユニークなキー・・・とりあえずid というカラムの id=10というレコードの処理ををAというクライアントがおこなっている場合、他のPCからBというクライアントがアクセスした場合、idが10以外のレコードであれば更新などの処理が行えるということでしょうか? たいして、MyISAMのテーブルごとロックというのは、Aというクライアントの処理がおわるまで、クライアントB、あるいはC等、一切、手をだせないということですね?