乐趣区

分布式并发场景下SpringSession(Redis) 的数据脏读问题

问题现象
问题来源于一个临时订单重复提交管控场景,通过在 Session 中写入本次提交的临时订单 ID 防止同个表单的重复提交。但在用户使用某些浏览器(如 QQ 浏览器、微信内置浏览器)时,仍有偶发性的重复提交现象。相关核心代码如下:
原因分析
该问题主要原因是因为当有 A、B 两个一样的请求时,如果在 A 还没响应完毕的时候 SpringMvc 又接收了 B 请求,B 请求在获取 Session 中的值时,会获取到 A 请求改写之前的数据。其根本原因在于 SpringSession 在写入或删除 Session 属性时,会根据配置中的 FlushMode 决定在什么时候序列化到 Redis,而默认的 FlushMode 为 ON_SAVE,API 原文是这样的:也就是说,在默认情况下只有在 Response 被提交时 Session 内容才会序列化到 Redis。所以导致了并发场景下的 Session 数据脏读问题
解决方案
目前我们采取将 RedisFlushMode 改为 IMMEDIATE,修改方法为在 @EnableRedisHttpSession 注解中指定 flushMode:如此修改后,在每次调用 removeAttribure 后,都能正确的观察到 Redis 中相应的属性被置为空,问题也就基本得到了解决。

退出移动版