私の環境は、Tomcat 7 で実行されている Web アプリケーションであり、フロントエンド ハンドラーの 1 つは、何らかの目的でデータベースからいくつかの整数を取得します。さまざまなユーザーのさまざまなリクエスト中に同じ整数が取得される可能性があるため、ハンドラーに単純な Map を静的フィールドとして追加して、既に読み取った整数をキャッシュする必要がありました。
問題は、リクエスト中にキャッシュされている値とキャッシュされていない値があることがわかったことです。マップへの一部の put-call が単純に無視されるか、値が格納されないか、またはその他のようです。Eclipse でアプリケーションをデバッグすると、put への呼び出しがアクセスされていることがわかりますが、その後、新しくフェッチされた値はキャッシュの一部ではなく、少なくとも Eclipse には表示されません。最後に取得した値を同じリクエストで 2 回取得する必要がある場合、Eclipse がキャッシュの一部として必要な値を表示しない場合でも、2 回目の呼び出しは明らかにキャッシュにヒットし、データベースへのアクセスを回避します。別のリクエストで同じ値が必要な場合、値は最初にデータベースから取得され、キャッシュに保存されます。Eclipse では表示されませんが、同じリクエスト内で取得できます。
私はここで本当に迷っています。何か非常に間違ったことをしているようです。しかし、Web アプリケーションにはキャッシュとして既に他の静的フィールドがあり、それらのような奇妙な動作は見られません。ただし、これらはマップではなく、カスタム オブジェクトまたは整数オブジェクトのみです。
private static Map<Integer, Integer> dirsOwnerCache = new TreeMap<Integer, Integer>();
private static Map<Integer, Integer> docsOwnerCache = new TreeMap<Integer, Integer>();
public static void someMethod()
{
[...]
Integer ownerId = null;
sync: synchronized(tabelle.equals("ordner") ? Util.dirsOwnerCache : Util.docsOwnerCache)
{
ownerId = tabelle.equals("ordner") ? Util.dirsOwnerCache.get(dsid) :
Util.docsOwnerCache.get(dsid);
if (ownerId != null)
{
break sync;
}
// fetching from database
[...]
ownerId = rs.getInt("besitzer_id");
rs.close();
stmt.close();
if (tabelle.equals("ordner"))
{
Util.dirsOwnerCache.put(dsid, ownerId);
}
else
{
Util.docsOwnerCache.put(dsid, ownerId);
}
}
[...]
}
問題を探すことができるヒントをいただければ幸いです。ありがとう!