PHP4.3.xとMySQL4.1.xを使用しています。


さて、InnoDBで作ったテーブルに、
PHPからアクセスするとします。

トランザクション処理をする際に、
BEGIN
を送って
SELECT
して
大丈夫なら
INSERT
して
COMMIT

だめなら
ROLLBACK
という感じの処理があったとします。



でも、少し疑問に思ったのが、
PHPからアクセスするユーザーが、
1つのユーザー(として定義)なので、
同時処理の時に、やっぱり、うまくトランザクション処理できていないような気がします。

また、よく耳にするのが、『MySQLのトランザクションはいい加減で危ない』と聞いたりします。

はたして、MySQL+PHPの環境のトランザクション処理は、どこまで信頼できるのでしょうか?

回答の条件
  • 1人5回まで
  • 登録:
  • 終了:2007/01/18 20:56:14
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:b-wind No.1

回答回数3344ベストアンサー獲得回数440

ポイント28pt

同じユーザーでもコネクションが違えばトランザクションは保証されます。

『MySQLのトランザクションはいい加減で危ない』

どこの誰がいったか知りませんが自分は聞いたことはありません。

MyISAM 形式ではトランザクションが使用できず、テーブルロックに頼るしかない状況を誤解されているのではないでしょうか?


たしかに、エンタープライズのレベルで使用できるかは議論の分かれるところかもしれませんが、Web 系のシステムのほとんどでは十分なレベルで信頼できます。

id:caster777

情報ありがとうございます。

なるほど、ロックは正常に行われているんですね。


例えば、

mysql_query("BEGIN;");

mysql_query("SELECT * from ....;"); //←適当

SelectしたデータをPHPの変数に入れて・・・

条件でOKなら、

mysql_query("INSERT INTO .....;"); //←適当

mysql_query("COMMIT;");

駄目なら

mysql_query("ROLLBACK;");

という処理のスクリプトに、

沢山のユーザーが同時にアクセスしても問題なく排他処理できるということで、問題ないんですよね??

2007/01/18 20:55:54

その他の回答2件)

id:b-wind No.1

回答回数3344ベストアンサー獲得回数440ここでベストアンサー

ポイント28pt

同じユーザーでもコネクションが違えばトランザクションは保証されます。

『MySQLのトランザクションはいい加減で危ない』

どこの誰がいったか知りませんが自分は聞いたことはありません。

MyISAM 形式ではトランザクションが使用できず、テーブルロックに頼るしかない状況を誤解されているのではないでしょうか?


たしかに、エンタープライズのレベルで使用できるかは議論の分かれるところかもしれませんが、Web 系のシステムのほとんどでは十分なレベルで信頼できます。

id:caster777

情報ありがとうございます。

なるほど、ロックは正常に行われているんですね。


例えば、

mysql_query("BEGIN;");

mysql_query("SELECT * from ....;"); //←適当

SelectしたデータをPHPの変数に入れて・・・

条件でOKなら、

mysql_query("INSERT INTO .....;"); //←適当

mysql_query("COMMIT;");

駄目なら

mysql_query("ROLLBACK;");

という処理のスクリプトに、

沢山のユーザーが同時にアクセスしても問題なく排他処理できるということで、問題ないんですよね??

2007/01/18 20:55:54
id:b-wind No.2

回答回数3344ベストアンサー獲得回数440

ポイント28pt

間違いありません。

http://php.benscom.com/manual/ja/function.mysql-query.php


ただし、コネクションプールを使用してちゃんとプールに返還しないなど、コネクションを平行して利用してしまった場合などに不具合が出る可能性はあります。

ただ、標準ではコネクションプールはないので心配ないと思いますが。

あと、mysql_connect も一度に一回しか呼び出してはいけません。

2回目からは別のコネクションになりますので。


これらは普通に作っていけば守るべき項目なので、ちゃんと作っている限りはまったく問題ありません。

id:caster777

ありがとうございます。

とても勉強になります。

なるほど、

mysql_connect();//←適当

mysql_query("BEGIN;");

mysql_query("SELECT * from ....;"); //←適当

mysql_connect();//←適当2回目

mysql_query("INSERT INTO .....;"); //←適当

mysql_query("COMMIT;");

というようなことはやっちゃ駄目と言うことですよね。


--------------------------------------------------


『MySQLのトランザクションはいい加減で危ない』

というのは、Oracleを使っている人が言っていたので、気になりました。

でも、彼は、MySQLをそんなに使ったこと無いのに、

『Oracleは有料、高価。MySQLは無料、オープンソース』

な感じで、皮肉っぽく言っただけかもしれません。

2007/01/18 20:55:50
id:b-wind No.3

回答回数3344ベストアンサー獲得回数440

ポイント26pt

なるほど、

中略

というようなことはやっちゃ駄目と言うことですよね。

そういう事ですね。


どうしても使いたい場合は、mysql_connect の返り値を受け取り、それを mysql_query の引数に渡してやって個別にきちんと管理すればOKです。

http://php.benscom.com/manual/ja/function.mysql-connect.php

http://php.benscom.com/manual/ja/function.mysql-query.php


というのは、Oracleを使っている人が言っていたので、気になりました。

でも、彼は、MySQLをそんなに使ったこと無いのに、

『Oracleは有料、高価。MySQLは無料、オープンソース』

な感じで、皮肉っぽく言っただけかもしれません。

それぞれ利用されるシチュエーションによって評価が変わってくるのでその方のいっていることが一概に正しい・間違っているとは言えないのですが、一般的に使われているレベルではまず問題はないです。

最近でこそ対 Oracle な機能を付けてきてはいますが、元々 MySQL は低機能・高速な軽量DBです。

重量級の Oracle と比べる事自体がナンセンスだと思います。

MySQL vs Oracle な議論は本題ではないのでこれぐらいで。

id:caster777

とってもよく分かりました。

本当にありがとうございました。

感謝です。

2007/01/18 20:55:45
  • id:b-wind
    ちょっと間違いがあったので補足。
    >mysql_connect も一度に一回しか呼び出してはいけません。

    >第3引数に True を指定した mysql_connect を呼び出す時は注意が必要です。
    に訂正します。


    デフォルトではすでに存在しているコネクションを返すようなので問題なさそうです。
    いずれにせよ今どのコネクションを使っているか、またそのコネクションでのトランザクションの状態はどうなっているかをきちんと管理して使う分には何の問題もありません。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません