这段时间发现系统取数据过程中,偶尔出现取数据错乱的问题,按逻辑应该取出A数据,结果取出了B数据。仔细检查了代码,
发现代码逻辑没有问题,瞬间就蒙了,是哪里出现问题了呢。仔细想了一下,以前都没出现问题,自从加了缓存之后就偶尔出现了问题,那肯定问题是缓存有问题。
仔细研究了缓存的源码,原来问题出现在DefaultKeyGenerator生成key上面。代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 |
public class DefaultKeyGenerator implements KeyGenerator { public static final int NO_PARAM_KEY = 0 ; public static final int NULL_PARAM_KEY = 53 ; public Object generate(Object target, Method method, Object... params) { if (params.length == 1 ) { return (params[ 0 ] == null ? NULL_PARAM_KEY : params[ 0 ]); } if (params.length == 0 ) { return NO_PARAM_KEY; } int hashCode = 17 ; for (Object object : params) { hashCode = 31 * hashCode + (object == null ? NULL_PARAM_KEY : object.hashCode()); } return Integer.valueOf(hashCode); } } |
从源码中我们发现,当参数:params有一个或0的时候,直接返回NULL_PARAM_KEY或者参数params[0],假如params参数大于1的时候返回的是各个参数的hash值相加的值+31*17。这样就出现问题了,虽然取A数据与取B数据的各个参数的值不一样,但是有可能它们参数的hashcode值是一样的,那么就可能出现取A数据把B数据取出来了。(cache中就像map一样,有key和value,根据key来取value值)。
比如下面代码,虽然参数值不一样但是key是相同的。
1
2
3
4
5
6
7
8
9
10 |
public static void main(String argv[]) { DefaultKeyGenerator g = new DefaultKeyGenerator(); Integer param0 = 1000000759 ; String param1 = "11" ; System.out.println( " param0=" +param0+ ", param1=" +param1+ " generate key: " +g.generate( null , null ,param0,param1)); Integer param01 = 1000000757 ; String param11 = "31" ; System.out.println( "param01=" +param01+ ",param11=" +param11+ " generate key: " +g.generate( null , null ,param01,param11)); } |
运行结果如下:
jsp复习资料汇总
[JSP]2017年1月24日asp教程编程辅导汇总
[ASP]2016年12月2日JSP快速入门教程汇总
[JSP]2016年12月2日jsp基本用法和命令汇总
[JSP]2016年10月3日ASP编码教程:如何实现/使用缓存
[ASP]2015年4月15日