[排坑]内存缓存(Ehcache)不小心的写数据,导致缓存被污染的事故

项目场景:

  • 在项目中使用基于内存(JVM)的缓存
  • 缓存了每个用户的基本信息
  • 用户的基本信息会同步到终端设备

问题描述:

  • 发现同步到终端设备的数据与数据库的不一致。但是很奇怪的是其中一个属性值小概率被置为空了。在数据库中值是存在的。

原因分析:

1,论证数据库数据与缓存数据的一致性,这里的一致性是指,我在数据库看到的,和被缓存的数据是否相同。

因为不排除,在查询数据库并缓存时,ORM映射问题导致某个属性没被赋值,但是这种问题一般出现频率是高频的,而不会是偶发。但也不排除偶发概率,因为在属性映射时,假设映射的代码在处理数据时根据某种特定情况而导致返回空。

2,是否存在非数据库的数据源更新缓存。笔者就是走进了这个坑。

  • 首先,我们使用的是内存缓存,当然这里的内存缓存应该理解为被缓存在JVM运行时中,这种缓存就是我们常说的Ehcache,和Redis不同是,Redis是单独的进程,而Ehcache是同一个进程
  • 假设我们对用户A对象进行了缓存,在不销毁的情况下,无论在何时获取用户A对象,返回的都是指向同一个对象地址的指针。在这种模式下,某个线程执行时,经过了用户A对象缓存的获取,通过参数被传递,慢慢的就可能忘记它是缓存返回的。也就慢慢不小心对这个缓存对象的某个属性进行了修改,在其他线程使用时,由于内存地址都是一样的,所以这个缓存的属性已经被偷偷的修改了,已经和数据库的不一致了。在开发时,一个不注意,这个缓存就会被慢慢的污染,最终面目前非,导致莫名其妙的问题。

总结

  • 在使用基于Ehcache、HashMap等在同一进程的缓存时,一定要注意,读出来的缓存不能被修改,这应该是规范。
  • 某些情况我们会对读取的缓存数据进行加工、转换,但同时加工、转换的载体又放在了缓存对象本身,此时我们应该对缓存对象进行深拷贝。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值