4

2つのJavaWebアプリは両方とも読み取り/書き込みであり、3つのスタンドアロンJava読み取り/書き込みアプリケーション(1つは電子メールで質問をロードし、1つはxmlフィードを処理し、もう1つはサブスクライバーに電子メールを送信します)はすべて休止状態を使用し、共通のコードベースを共有します。

最近遭遇した問題は、電子メールを介してロードされた質問が、Webアプリの1つで作成された質問を上書きすることがあるということです。これらは別々の質問であり、別々のIDが必要であることに注意してください。当初、これはキャッシュの問題であると考えていました。2番目のレベルのキャッシュをオフにしてみましたが、違いはありません。

<property name="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.cache.use_second_level_cache">false</property>

質問:

@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id", unique = true, nullable = false)
@DocumentId
public Integer getId() {
    return this.id;
}

MySQLを使用しています。

CREATE TABLE  `question` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  ...
  PRIMARY KEY (`id`),
  ...
) ENGINE=InnoDB DEFAULT CHARSET=utf8

セッションを明示的に開始および終了するのではなく、休止状態でを介してセッションを管理しますUtil.getSessionFactory().getCurrentSession()

この段階では、クラスター化された第2レベルのキャッシュをセットアップするのではなく、複雑さの別のレイヤーが作成され、アプリ全体から得られるパフォーマンスのレベルに満足しています。

では、Webアプリでopen-session-in-viewパターンを実装し、スタンドアロンアプリでセッションを手動で管理することは、これを修正するように聞こえますか?

または他の提案/アイデアをお願いしますか?

4

2 に答える 2

3

すべての質問には ID があるため、すべての質問が MySql データベースから取得されると仮定します。

問題を透明なオブジェクトとしてメモリに保存する必要はなく、提示するたびにすべての問題を選択すると仮定すると、簡単な提案が 1 つあります。

ID ジェネレーターをデータベース内のシーケンスに置き換えます。(最終的に、MySql の自動番号としての ID)。次に、アプリケーションではなくデータベースが、すべての質問が一意の ID を取得することを保証します。

このソリューションは非常にシンプルで、複雑さを軽減します。また、さまざまなソースから受信したすべての質問をデータベースに保持し、ここから選択する場合にのみ機能します。

この解決策でパフォーマンスの問題が発生する場合は、Hibernate id ジェネレーターがどのように機能するかをさらに調査する必要があります。Hibernate は、さまざまなシナリオ用にいくつかの異なるジェネレーターを提供します。

この助けを願っています!

于 2010-05-12T09:21:47.740 に答える
0

この問題は、Hibernate とはまったく関係がないことが判明しました。

ステージング サーバー上のデータベース テーブルの 1 つが、クリーンアップする必要のある古いデータでいっぱいになりました。これにより、最初は id が上書きされているように見えましたが、さらに調査したところ、そうではないことが判明しました。

危険なデータを削除すると、すべてがうまくいきました。

于 2010-05-21T10:52:34.757 に答える