2

私はmysqlでJDBCを使用しています。単一のトランザクションで実行しているかなり複雑な一連の挿入と更新があります。これはほとんどの場合機能しているように見えますが、約 1% の確率で、テーブルの 1 つのデータが一貫性のない状態にあることに気付きます。

エラーが発生した場合はトランザクションをロールバックしていますが、デバッグを開始する方法がわかりません。私のセットアップは一般的に次のようになります。

try {
    conn.setAutoCommit(false);  

    PreparedStatement stmt1 = conn.prepareStatement("insert into table1");
    stmt1.executeUpdate();
    stmt1.close();

    PreparedStatement stmt2 = conn.prepareStatement("update table2");
    stmt2.executeUpdate();
    stmt2.close();

    ... more statements ...

    conn.commit();
} 
catch (Exception ex) {
    conn.rollback();
}

2010 バージョンの mysql を使用しています。それを更新してみるかもしれませんが、不整合の原因はアプリケーション コードの何かにあると感じています。

データベース レベルで役立つと思われるデバッグ ツールはありますか? 他のポインタはありますか?私はすべてデフォルト設定で JDBC を使用しています。この種のシナリオで使用する必要がある、より厳密なトランザクション レベルがあるのでしょうか?

ありがとう

----- 注 ----- 私のテーブルはすべて InnoDb です。

4

2 に答える 2

0

うーん.. 面白い。はい、うまくいくはずです。複数のテーブル間で非常に巨大なトランザクションを何度も使用しましたが、奇妙なことさえ経験したことはありません...
矛盾を引き起こしたのはあなたではありませんか(これがここで何を意味するにせよ、あなたはこれを指定しませんでした)?間違ったものを挿入/更新するだけですか?:-)

ただのアイデアです - 私たちはこれに何度か遭遇しました。デッドロック解消。それを処理するために使用されるDBサーバー。複数の並列スレッドがあり、トランザクション ブロックがより多くのテーブルを操作している場合、デッドロックが発生する可能性が高くなります。この場合、トランザクションの一部が DB サーバー自体によって中止 (およびロールバック) される可能性があります。そして、それらのトランザクションはエラーになります。

上記のコードは、例外の場合にのみロールバックします (中止されたトランザクションは既にロールバックされているため、あまり機能しません..) が、例外を印刷/ログに記録しようとしましたか? そうでない場合は、する必要があります。

もちろん、トランザクションは互いに分離して実行されます。しかし、これにより、この奇妙な動作が 1 ~ 2% のケースでしか発生しない理由を説明できます...

mysql サーバーのログも確認する必要があります。サーバー自体が何らかの理由で失敗する可能性もあります。もう 1 つのヒント: 「mysqltop」(または「mtop」、このツールの名前を正しく覚えていることを願います..) を実行してみてください。これにより、DB サーバー内で何が起こっているかを監視して表示できます。ただし、ほとんどの場合、SQL のパフォーマンスを追跡するために使用されますが、これは失敗も示しています。多分これを実行することもあなたを助けることができます...

于 2013-02-16T20:53:11.617 に答える
0

おそらく、ステートメントで DDL (create table、a​​lter table など) を使用していませんか?

MySQL についてはよくわかりませんが、DDL ステートメントをロールバックできない可能性があります。

例えば:

  • PostgreSQL は DDL をロールバックできます。
  • Oracle は、DDL を実行する前にコミットを実行します。

ここを参照してください: http://dev.mysql.com/doc/refman/5.0/en/cannot-roll-back.html

于 2013-02-16T21:07:21.037 に答える