2

外部イベント (着信測定データ) が発生すると、Java コードのイベント ハンドラーが呼び出されます。データは MySQL データベースに書き込む必要があります。これらの呼び出しの頻度が高いため (1 秒あたり 1000 件以上)、挿入を効率的に処理したいと考えています。残念ながら、私はプロの開発者ではなく、データベースの馬鹿でもあります。

効率の側面を無視すると、私のコードはおおよそ次のようになります。

public class X {

    public void eventHandler(data) {
        connection = DriverManager.getConnection()
        statement = connection.prepareStatement("insert …")
        statement.setString(1, data)
        statement.executeUpdate()
        statement.close()
        connection.close()
    }
}

私の理解では、ステートメントで addBatch ()executeBatch( )を呼び出すことで、物理ディスクへのアクセスを制限して、1000 回目の挿入ごとに言うことができます。ただし、上記のコード スケッチでわかるように、ステートメントオブジェクトはeventHandler()の呼び出しごとに新しくインスタンス化されます。したがって、バッチ メカニズムはこのコンテキストでは役に立たないというのが私の印象です。自動コミットをオフにしてから接続オブジェクトでcommit()を呼び出すのと同じです。接続オブジェクトは挿入のたびに閉じられるからです。

接続ステートメントをローカル変数からクラス メンバーに変換し、プログラムの実行中にそれらを再利用することができました。しかし、データベース接続を常に開いたままにしておくのは悪いスタイルではないでしょうか?

解決策は、データを手動でバッファリングし、適切なバッチを収集した後にのみデータベースに書き込むことです。しかし、これまでのところ、データベースにバッファリングをさせる方法を教えてくれることを願っています。

4

2 に答える 2

1

接続とステートメントをローカル変数からクラス メンバーに変換し、プログラムの実行中にそれらを再利用することができました。しかし、データベース接続を常に開いたままにしておくのは悪いスタイルではないでしょうか?

ほとんどの (データベース) 接続プールは通常、少なくとも 1 つ以上の接続を常に開いたままにしておくように構成されていることを考えると、それを「悪いスタイル」とは呼びません。これは、各データベース操作で新しい接続を開始するオーバーヘッドを回避するためです (必要な場合を除き、既に開いているすべての接続が使用中であり、プールでそれ以上の接続が許可されている場合)。

この場合、おそらく何らかの形式のバッチ処理を使用します(ただし、もちろん、すべての要件/環境などを知っているわけではありません)。データを別の場所ですぐに利用できるようにする必要がない場合は、データを書き込むための何らかの形式のジョブ キューを構築し、そこに着信データをプッシュして、他のスレッドに N サイズのデータ​​ベースへの書き込みを処理させることができます。バッチ。java.util.concurrentパッケージで利用できるクラスを見てみましょう。

于 2013-02-05T21:24:54.430 に答える
0

を使用しLinkedList<>てデータをバッファリングし(キューのように)、データをdbmsに保存し、必要に応じて別のスレッドで定期的に実行することをお勧めします(おそらく2秒ごと?)

javaでlinkedlistを使用してキューを作成する方法を参照してください

于 2013-02-05T21:01:33.993 に答える