大規模なトランザクションの一部としてレコードを更新するプロセスがある MySQL に接続されている Grails ベースのアプリケーションに問題があります。このプロセスは、追加の変更を実行する Quartz ジョブを介して 2 番目のスレッドも開始します。通常、Quartz ジョブは最初のスレッドがトランザクションをコミットする前に開始されるため、ジョブは最大 1 分間ループし、レコードが期待される状態に変化するかどうかをチェックします。奇妙なことに、一部の環境では一貫して機能し、ある環境では一貫して失敗し、さらに別の環境ではまれに失敗します。
私の質問は、MySQL が 2 つの同時接続間のトランザクション コミットをどのように認識するかに関するものです。接続 A がコミットを実行すると、接続 B からの後続のクエリがコミットされた変更を認識することが予想されます。私の場合、接続 B は、接続 A がコミットする前に同じクエリを 1 回以上作成します。mySQL が接続のクエリ結果をキャッシュしているようです。奇妙なことに、接続 B が繰り返しクエリを実行して古い値を取得している間に、mysql クライアントを介して同じクエリを発行し、新しい値を確認できます。キャッシングの問題や同時実行の問題を知っている人はいますか?
上記の観察では、発生している個々の更新、コミット、およびクエリを確認するために、MySQL ログを有効にしています。
以下に示すように、さまざまな環境で異なるバージョンの MySQL が使用されています。環境を最新の MySQL にアップグレードして、問題が解決するかどうかを確認しています。
5.0.51a - 発生頻度が低く非常に安定している 2 つの環境ですが、1 つの環境では、週末にかけて中程度のトラフィックで発生数が増加し始めました。
5.1.55 - 1 つの環境が一貫して失敗する
ありがとう、
ジョン