论坛首页 Java版 Webwork

请教一个问题,如何强制清除OSCache中缓存的对象?

浏览 4946 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
最后更新时间:2005-06-09
在使用OSCache的Filter过滤器并缓存网页的时候,我遇到这样的情况,当一个用户访问我的某个页面,如果session过期,我会让他跳转到首页,然后用户重新登陆,再次访问那个曾经session过期的页面,会发现仍然跳转到首页。于是我打算在session过期的时候,强制清除Cache中被缓存的对象。

我尝试在Filter中清除cache,但是Cache类的clear()方法是protected的,无法获取到,虽然我能够得到需要清除的页面对象放在Cache中的key,但是Cache类并没有提供remove之类的功能方法。而Filter中的destroy()方法是空的,按照API上说,可以清除Filter,但是我发现没有效果。

请问有什么办法可以清除cache吗?谢谢赐教,不胜感激。
   
最后更新时间:2005-06-09
flushAll / flushEntry
   
0 请登录后投票
最后更新时间:2005-06-09
没有效果呀,设断点观察过,cachemap中的对象并没有被清空。。。另外,flush方法按照我的理解,似乎只是为了刷新一下cachemap中的对象,以免出现逻辑上更新cachemap中对象但是实际上并没有更新的情况,相当于避免“不同步”,但是并不会删除它们。

要怎样才可以删除cachemap中的对象呢?
   
0 请登录后投票
最后更新时间:2005-06-09
偶说的方法是在GeneralCacheAdministrator这个类下面的......
   
0 请登录后投票
最后更新时间:2005-06-09
我使用的是web的filter,所以用ServletCacheAdministrator,的确和你讲的类不一样,为了测试,我直接在原来的CacheFilter的doFilter方法中,在
[code:1]// Only cache if the response was 200
if (cacheResponse.getStatus() == HttpServletResponse.SC_OK) {
//Store as the cache content the result of the response
cache.putInCache(key, cacheResponse.getContent());
updateSucceeded = true;
}[/code:1]
之后,我加行代码:
[code:1]cache.flushAll(new Date());
[/code:1]
设断点之后,我发现flushAll并没有清除cache。

你说的类GeneralCacheAdministrator中flushAll方法,看源代码:
[code:1] /**
     * Flush the entire cache immediately.
     */
    public void flushAll() {
        getCache().flushAll(new Date());
    }[/code:1]
实际上还是调用Cache类的
[code:1] /**
     * Flush all entries in the cache on the given date/time.
     *
     * @param date The date at which all cache entries will be flushed.
     */
    public void flushAll(Date date) {
        flushAll(date, null);
    }[/code:1]
所以我应该是按照你所讲述的方式调用了flushAll方法。
   
0 请登录后投票
最后更新时间:2005-06-09
你的oscache版本是?偶下面的unit test代码在2.0以上都是通过的......

public class OscacheTest extends TestCase {
    private GeneralCacheAdministrator ca = new GeneralCacheAdministrator();

    public void testFlush() {
        ca.putInCache("key1", "object1");
        ca.putInCache("key2", "object2");
        assertEquals("object1", get("key1"));

        ca.flushEntry("key1");
        assertNull(get("key1"));
        assertEquals("object2", get("key2"));

        ca.flushAll();
        assertNull(get("key2"));
    }

    private Object get(String key) {
        try {
            return ca.getFromCache(key, CacheEntry.INDEFINITE_EXPIRY);
        } catch (NeedsRefreshException e) {
            ca.cancelUpdate(key);
            return null;
        }
    }
}
   
0 请登录后投票
最后更新时间:2005-06-09
cache.putInCache(key, cacheResponse.getContent());
中的cache是不是ServletCacheAdministrator对象?
   
0 请登录后投票
最后更新时间:2005-06-10
我用的是最新的oscache2.1.1,里面确实和2.0不太一样,不过应该改动不大。我主要是使用ServletCacheAdministrator,不过应该和GeneralCacheAdministrator在理论上没有太大区别,只是实现不同罢了。


[code:1] private Object get(String key) {
try {
return ca.getFromCache(key, CacheEntry.INDEFINITE_EXPIRY);
} catch (NeedsRefreshException e) {
ca.cancelUpdate(key);
return null;
}
}[/code:1]
我对你这句的测试有些问题。因为在我实际测试中,发现ca.getFromCache(key, CacheEntry.INDEFINITE_EXPIRY); 每次都会抛出异常,所以你总会得到null的值,但实际上并没有清除cache。

如果将private Object get(String key)方法catch里面的return null改为return "123"之类,你就可以看到的结果。
   
0 请登录后投票
最后更新时间:2005-06-10
看oscache的test code或者查文档, 对NeedsRefreshException的设计已经解释得很清楚了:
引用

This exception is thrown when retrieving an item from cache and it is expired. Note that for fault tolerance purposes, it is possible to retrieve the current cached object from the exception.
January, 2004 - The OSCache developers are aware of the fact that throwing an exception for a perfect valid situation (cache miss) is design smell. This will be removed in the near future, and other means of refreshing the cache will be provided.
   
0 请登录后投票
最后更新时间:2005-06-10
谢谢Readonly的帮助,我发觉自己对缓存技术的思维方式应该改变了。我以前的理解过于简单,认为缓存不外呼就是一个collection,对象要么被放进去,要么就从集合中清除,没有考虑到对象依然存在于集合中却过期的情况,而且对OSCache的文档知之甚少,目前似乎也没有看到对OSCache理论逻辑上的介绍。

现在,我还是有些不明白为什么OScache不提供直接剔除被缓存对象的方法,不过我会先去OSCache的邮件列表瞧瞧,再仔细看看其源代码,好好理解一下缓存技术的思维逻辑。

再次感谢:)
   
0 请登录后投票
论坛首页 Java版 Webwork

跳转论坛:
JavaEye推荐