2012-03-30 22 views
11

各クライアントが同時に動作するため、クライアントが切断された直後にトランザクションをロールバックするようにMySQLサーバを作成する必要があります。私はinnodb_rollback_on_timeoutのようにMySQLのサーバー・オプションを設定し、使用していた接続が紛失/切断されたMySQLロールバック

START TRANSACTION; 
SELECT MAX(ID) FROM tblone FOR UPDATE; 
#... lock wait time out will occur here 

:クライアントBで

START TRANSACTION; 
SELECT MAX(ID) FROM tblone FOR UPDATE; 
#... then disconnect your connection to the server 

:問題は、クライアントAで

(のInnoDBテーブルタイプを使用して)これらのように再現することができます両方のクライアントでmysqlのクライアントmysql --skip-reconnect。私はネットワーク上で1台のサーバーと2台のクライアントを使ってこれを試しました。私はSELECT ... FOR UPDATE;行の後にネットワークを物理的に切断しました(ケーブルを外します)。私は他のクライアントにトランザクション(ロック、更新)をtbloneで使用できるようにする必要があります。クライアントAが切断された後、クライアントAのトランザクションをロールバックする必要があります。

+0

興味深い質問です。私はこれが自動だと思った!だから私は 'innodb_rollback_on_disconnect'のようなものが必要です。それは素晴らしいでしょう、私は、デフォルトでなければならないと言っています!それはmysqlの合理的な変更要求です。 – TMS

答えて

10

クライアントを物理的に切断すると、通常の切断(ロールバックを引き起こしていた)が送信されず、MySQLプロトコルはあまりチャットされないので、サーバーはクライアントが存在しないことを知らない。クライアントとサーバーが内部的に話す他のデータベースシステムと比較すると、これはプロトコルの欠陥であると私は思う。

とにかく。変更可能な変数は2つあります。彼らは基本的に同じことをしますが、異なるクライアントにします。

最初はwait_timeoutであり、javaやphpのようなアプリケーションクライアントによって使用されます。

他はinteractive_timeoutあり、それは両方のケースで

秒数後に接続を殺し、そうする場合は、すべてのすべてのトランザクションとのリリースをロールバックしにサーバー(あなたのテストのように)mysqlクライアントによって使用されていますロック。

+0

お返事ありがとうございます。両方のオプションを使用して試してみましたが、60秒(実験用)に設定しましたが、別の問題が発生します。 60秒間の非アクティブ(アイドル)の後、接続は自動的に閉じられ、次のクエリでエラーが発生し(サーバーがなくなった)、自動的に再接続します。接続が確実に行われるように59秒ごとにクエリを行うコードを作成する必要がありますか?それとも別の方法がありますか? 60秒以上かかる長いクエリは、プロセスの途中で切断されますか? – qsoft

+0

私はトランザクション中にこの動作が必要なだけなので、トランザクションの直前に 'SET SESSION wait_timeout = 60'のようなことをして、コミット/ロールバック後にリストアできますか? – qsoft

+0

ストアドプロシージャ内で、またはトランザクションを開始する前に別のステートメントとして変更する必要があります。 あなたはアイドル状態の接続が閉じられていることを正しく認識しています。それがどのように動作するのですか。しかし、長時間実行しているクエリは、私が見た限りでは "アイドル"としてカウントされません( 'select 1、sleep(61)dualから'テストするのが簡単です) –

関連する問題