2

キャッシュ()をメモリに保持するJava Webアプリ(TomcatにWARをデプロイMap<Long,Widget>)があります。テーブルを含むPostgresデータベースがありwidgetsます:

widget_id | widget_name | widget_value
(INT)       (VARCHAR 50)  (INT)

WidgetPOJOとテーブルレコード間のO/Rマップwidgetsには、MyBatisを使用しています。widgetsテーブルの値が変更されるたびにJavaキャッシュ(マップ)がリアルタイムで更新されるソリューションを実装したいと思います。たとえば、30秒ごとにテーブルをチェックするポーリングコンポーネントを使用することもできますが、ここではポーリングが適切な解決策とは思えません。これが私が提案していることです:

  1. ストアドプロシージャを呼び出すPostgresトリガーを記述します(run_cache_updater()
  2. プロシージャは順番にシェルスクリプトを実行します(run_cache_updater.sh
  3. スクリプトbase-64は、変更されwidgetsたレコードをエンコードしてから、エンコードされたレコードをHTTPURLにcURLします
  4. Java WARには、cURLされたURLをリッスンするサーブレットがあり、それHttpServletRequestsに送信されたものを処理します。Widgetそれはbase-64でレコードをデコードし、どういうわけかそれをPOJOに変換します。
  5. キャッシュ(Map<Long,Widget>)は正しいキー/値で更新されます。

このソリューションは扱いにくいと感じるので、私は最初に、そこにあるJava/Postgresの達人がそのような状況をどのように処理するのか疑問に思っています。ここでポーリングはより良い/より単純な選択ですか(私は頑固ですか?)私が見落としている別の/より良い/より標準的な解決策はありますか?

widgetsそうでない場合、このソリューションが変更されたレコードをPostgresからアプリケーション層にプッシュする標準的な方法である場合、レコード全体がcURLステートメントに渡されるように、トリガー、ストアドプロシージャ、およびシェルスクリプトを作成する方法を検討しています。。ここで助けてくれてありがとう。

4

1 に答える 1

4

MyBatis と話すことはできませんが、PostgreSQL にはパブリッシュ/サブスクライブ システムが組み込まれており、ハッカーを大幅に削減してこれを行うことができると言えます。

widgetsまず、すべての挿入、更新、および削除操作で実行されるトリガーを設定します。主キーと. (まあ、PL/pgSQL からは、おそらく.NOTIFYwidgets_changed, idPERFORM pg_notify(...)

クライアントでは、このマップを最新の状態に保つ専用のスレッドを実行する必要があります。PostgreSQL に接続して、通知のキューイングを開始し、マップにデータを入力して、通知が到着するのを待ちます。(通知を確認するには JDBC ドライバーをポーリングする必要があるようです。これはひどいものですが、思ったほど悪くはありません。具体的な実装については、 PgNotificationPollerを参照してください。) 通知が表示されたら、指定されたレコードを検索し、マップを更新します。と の間でレコードが変更される可能性があるため、イニシャルの前にすることが重要であることに注意してください。LISTENwidgets_changedSELECT * FROM widgetsLISTENSELECT *SELECT *LISTEN

このアプローチでは、PostgreSQL がアプリケーションについて何も知る必要はありません。通知を送信するだけです。残りはアプリケーションが行います。シェル スクリプト、HTTP、およびコールバックがないため、データベースを再構成することなく、アプリケーションを再構成/再デプロイできます。これは単なるデータベースであり、バックアップ、復元、複製などを追加の複雑さなしに行うことができます。同様に、アプリケーションに余分な複雑さはありません。必要なのは、すでにある PostgreSQL への接続だけです。

于 2012-12-04T02:16:33.350 に答える