2017-01-11 4 views
0

私はmariadbクラスターを作成しました。私はJavaアプリケーションを取得して、それらの1つが消滅したときに別のホストにフェイルオーバーできるようにしようとしています。jdbcでgalera mariadbを使用

"jdbc:mysql:sequential://host1,host2,host3/database?socketTimeout=2000&autoReconnect=true"で接続を作成するアプリケーションを作成しました。アプリケーションは毎秒ループでクエリを作成します。私は、アプリケーションが現在のクエリを実行しているノードを殺した場合(Statement.executeQuery())私はタイムアウトのためのSQLExceptionを取得します。私は例外をキャッチし、再度実行文を、私は、要求が別のサーバーに送信されているので、その場合のフェールオーバーがOKに動作することを確認することができます。しかし、私はのexecuteQuery()が例外をスローし、静かに、自動的に別のサーバを再試行しないだろうと期待していました。

私は例外を処理する必要がないと明示的にクエリを再試行する必要があると仮定して間違っていますか?それを実現するために何か設定が必要なのでしょうか?

答えて

2

それは以下の理由のための自動再接続に危険です。

ここで、(行3)でサーバーがクラッシュするとします。トランザクションはロールバックされます。製作した例では、tblのロックを解除するだけです。

ここで、自動再接続中に同じ行で同じトランザクションを実行すると、他の接続が成功したとします。

自動再接続では、最初のスレッドは、トランザクションの前半がロールバックされていないことに気付かず、最新のデータに基づいてUPDATEを実行します。

BEGINに戻って「トランザクションを安全にする」ためには、例外を取得する必要があります。

これはとにかく必要です.Galeraでは、にはのクラッシュが発生する可能性があります。 で同じトランザクションを実行している2つのスレッド ...それぞれが成功し、COMMITに到達すると、その時点でGaleraの魔法が発生し、COMMITの1つが失敗すると言われます。 「正しい」レスポンスは、障害のために選択したサーバー上のトランザクション全体を再生です。

ガレラは、ガレラ以外と違い、エラーのチェックはCOMMITで行う必要があることに注意してください。 (非ガレラから移行開発者とデータベース管理者を狙っ)

もっとGalera tips

+0

ありがとうございました。私はそれを知らなかった。この情報は私にとって非常に便利ですが、私の質問に完全には答えていません。 (例外を生成してから再接続するのではなく)クエリ中にドライバが再接続する可能性があるかどうかは分かりますか?私は非常に基本的なクエリを持っているので、私はそれを危険にさらすことができると思う。しかし、あなたの答えは将来私にとっては間違いないでしょう。 – ps197xv

+0

申し訳ありませんが、私はJavaコネクタについてよく分かりません。 –

0

フェイルオーバーは、そのアプリケーションが例外を処理する必要がないという意味ではありません。

ドライバは、接続が失われたときに別のサーバーに再接続しようとします。

ドライバが別のサーバーに再接続できないとSQLNonTransientConnectionExceptionがスローされた場合、プールは自動的にそれらの接続を破棄します。

接続が復旧した場合、クエリがトランザクション内になく、現在接続がread-only mode(Spring @Transactional(readOnly = false)を使用)になっている場合、再起動クエリが安全である場合があります。その場合、MariaDb java接続は自動的にクエリを再起動します。これらの特定のケースでは、例外はスローされず、フェールオーバーは透過的です。

ドライバはトランザクション中に現在のクエリを再実行できません。
トランザクションがなくても、クエリがUPDATEコマンドの場合、ドライバは最後の要求がデータベースサーバによって受信され、実行されたかどうかを知ることができません。

その後ドライバが(「25」= INVALID_TRANSACTION_STATEではSQLStateの初めに)SQLExceptionが送信されます、そして、それはこれらのケースを処理するために、アプリケーション次第です。

関連する問題