## 先看问题:
一. 问题场景
1.使用缓存(HashMap)保存了一个数据库持久化dao层方法getUser()返回的Used对象,
2.我们知道dao层的方法返回的对象都是在dao方法中创建的。
3.场景,在调用这个dao层的方法getUser()方法时先判断这个对象在缓存中是否存在,如果存在则返回缓存中的User对象,不存在则执行getUser()方法。
4.在获取到User对象之后我要对User对象里面的某个int字段加1,然后显示出来。
二.使用场景
1.在这个整个一套逻辑中我发现缓存其实返回的是User对象的引用。而getUser()方法返回的是一个全新的User对象,
2.在多次执行时如果命中缓存时User对象的这个int类型字段会一直加下去。而没有命中缓存时则是数据库中的值+1不会一直加下去;
三.分析
1.此问题出现导致了返回的User对象里面的这个int类型的字段数据不正确,跟缓存的
命中情况有直接关系,命中缓存时得到的数值总是比没有命中是的数值大。
四.解决办法
1.解决这个问题的最有效方法就是如果是使用缓存的方法,对返回的对象不能做属性的修改。
2.使用自定义缓存时,在每次从缓存里面取数据时返回这个缓存的一个副本,既克隆的一个对象
五.分析解决办法
1.很明显解决办法1肯定不行,因为在显示的时候一般都需要对返回的对象的属性进行更改或包装,然后在set到这个对象那个中,这样就导致上面的问题了。
2.如果我们现在使用的是第三方的缓存技术如ehcache,我们会发现同样的问题,解决办法2可以对ehcache的获取缓存对象进行封装,实现克隆的对象,但是如果使用ehcache和spring注解整合使用注解来注解方法或的时候,我们就没有办法了,使用注解这个问题还是存在。
3.那么问题来了,我要使用spring注解+ehcache来对我dao层的方法进行缓存,并且配置了ehcache缓存超过一定的量时缓存到磁盘而且可以持久化缓存,现在出现了如上的场景,这个问题怎么办啊?
然后多次执行后面的这个方法时,这个Praise属性一直会加1。