有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java静态映射为缓存丢失或未设置值

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

现在的问题是,在请求期间,我发现一些值被缓存,而其他值则没有。似乎对映射的一些put调用被忽略了,或者没有存储值,或者其他什么。如果我在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);
        }
    }
    [...]
}

如果能给我一些提示,我将不胜感激。谢谢


共 (1) 个答案

  1. # 1 楼答案

    我想我发现了问题所在:我的环境有点特殊,因为我的web应用程序由一个Servlet/JSP前端和一个Axis 2 SOAP服务作为后端组成。为了有选择地摆脱SOAP,我们决定使用一些类加载器操作,特别是使用URLClassLoader,将Axis 2服务作为本机Java类提供,并使用URLClassLoader本机加载后端类,其中包含指向后端的路径和我们使用的所有LIB等。JAVAlang.ClassLoader。loadClass表示,通常在加载类之前使用findLoadedClass,以查看该类之前是否已加载,并且不再加载。在我的环境中,或者在我使用URLClassLoader的方式中,情况似乎并非如此,因为在每次请求期间加载类的每次调用都会生成一个新的类对象。因此,在请求期间新创建了静态字段。虽然我不知道为什么在Eclipse中,我的缓存中的一些值在请求期间是持久的,但可能一些加载的类是通过URLClassLoader缓存的

    然而,在使用URLClassLoader之前,我为一次加载的类添加了自己的静态映射作为缓存,现在我的后端缓存像预期的那样工作:它们的值在请求期间保持不变,并且在Eclipse调试器中正确可见