0

我的环境是在 Tomcat 7 中运行的 Web 应用程序,我的一个前端处理程序出于某种目的从数据库中检索一些整数。在不同用户的不同请求期间,可能会检索到相同的整数,这就是为什么我想在我的处理程序中添加一个简单的 Map 作为静态字段来缓存已经读取的整数。

现在的问题是,在请求期间,我发现一些值被缓存,而另一些则没有。似乎某些对地图的调用被简单地忽略了,或者值没有被存储或其他什么。如果我在 Eclipse 中调试应用程序,我可以看到调用 put 被访问,但之后新获取的值不是缓存的一部分,至少 Eclipse 没有显示它。如果在同一个请求期间最后一次获取的值需要被获取两次,那么第二次调用显然会命中缓存并避免访问数据库,即使 Eclipse 没有将所需的值显示为缓存的一部分。如果另一个请求中需要相同的值,则首先从数据库中再次获取该值,并将其存储在缓存中,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);
        }
    }
    [...]
}

我将不胜感激任何可以寻找问题的提示。谢谢!

4

1 回答 1

0

I think I found what the problem is: My environment is a bit special as my web application consists of a Servlet/JSP-Frontend and an Axis 2 SOAP-service as backend. To optionally get rid of SOAP we decided to make the Axis 2 service available as a native Java class using some ClassLoader manipulations, especially using URLClassLoader with paths to our backends and all the libs we use etc. and load backend classes natively using URLClassLoader. java.lang.ClassLoader.loadClass says that normally findLoadedClass is used before a class is loaded to see if it already has been loaded before and don't load it again. This doesn't seem to be the case in my environment or how I use URLClassLoader, because each invocation to load a class during each request produced a new class object. Because of this the static field were newly created during the requests. Though I don't know why it seemed in Eclipse that some values of my caches were persistent during requests, maybe some loaded classes got cached by URLClassLoader somehow.

However, I added my own static map as cache for once loaded classes before using URLClassLoader and now my backend caches work like expected: Their values persist during requests and are properly visible in Eclipse debugger.

于 2013-07-04T06:57:49.860 回答