1

書き込みが多い組み込みデータベース (H2) にアクセスしようとしています (10/秒、すべてイベントのカウンターです)。そして、そのデータを 1 分程度に 1 回読み取る必要があります。読み取ったら、カウンターをリセットする必要があります。

この動作を実現しようとしています (疑似コード):

//Writer thread
SELECT count FROM counters_db WHERE type="eventID1";
if count:
   count++;
   UPDATE counters_db SET count=count WHERE type="eventID1";
else:
   INSERT INTO counters_db(eventID, count) VALUES(1, "eventID1")

//Reader thread
DATA = SELECT * FROM counters_db;
TRUNCATE TABLE counters_db;
process(DATA) <--Do something with the data

両方のスレッドが並行して実行されています。

私が見る問題は次のとおりです。

  1. ライター スレッドの SELECT-UPDATE-INSERT パラダイムは、バグがあるように見えます。何かが挿入され、リーダースレッドの選択の一部ではなかった場合、リーダースレッドでTRUNCATEすると、データが失われる可能性があります。

  2. カウントを更新してから切り捨ててフラッシュするよりも、このデータを処理するためのより良い方法があると確信しています。値を挿入するだけで機能し (つまり、挿入するだけの書き込みスレッドの非常に単純なロジック)、読み取りスレッドは処理する行を認識します (しかし、どのように?)。このアプローチには、組み込みデータベースに大量のレコードを作成するというリスクもあります。どうすればそれを処理できますか?

この問題にアプローチする最善の方法は何ですか? 明らかな何かが欠けていますか?

4

1 に答える 1

0

#1 (リーダー スレッドを無視) については、2 つのライター スレッドが同時に挿入を試み、データが失われるという問題があります。

  • カウンタの挿入にはグローバル ロックを使用します。
  • 通常、データベースには、これを行う updateOrInsert スタイルのコマンドがあります。

#2については、私が考えることができるいくつかのオプションがあります:

  • ロックを使用します (各カウンターに細かく設定するか、データベース システムでアトミック更新を許可します)。
  • 一部のデータを失うことを覚悟してください。
  • 読み取り側では、カウンター値が何であるかを確認し(おそらくこれをデータベースに書き戻すことができます)、カウンターをリセットせず、単にデータ<以前の値を無視します。
于 2013-01-10T06:34:17.587 に答える