当前位置: 首页 > news >正文

网站设计制作花多少钱选服务好的佛山网站建设

网站设计制作花多少钱,选服务好的佛山网站建设,青海格尔木建设局网站,做网站多少钱_西宁君博相约结论 SecurityUtils.getSubject().getPrincipal()实际用的也是ThreadLocal#xff0c;而ThreadLocal和线程绑定#xff0c;异步会导致存数据丢失#xff0c;注意#xff01; 业务背景 最近#xff0c;系统偶尔会出现excel导入成功#xff0c;但系统却提示存在进行中的…结论 SecurityUtils.getSubject().getPrincipal()实际用的也是ThreadLocal而ThreadLocal和线程绑定异步会导致存数据丢失注意 业务背景 最近系统偶尔会出现excel导入成功但系统却提示存在进行中的导入的问题并且等待了较长的时间还是不行。这边跟进排查一下。 实现现状 导入的时候会对参数进行校验其中就有数据重复校验。 看了一下前辈是用redis的set来进行的去重校验操作。用LoginUser获取用户id固定前置用户id拼接作为redis的key需要去重的字段拼接成map作为值。主业务方法结束的时候用传入的LoginUser的用户id去拼接key来删除key因为校验方法是框架带的所以无法传参将LoginUser传进去。 判断是否存在正在进行的导入是直接拼接key来查rediskey存在则说明有正在进行中的导入。 private boolean hashCacheExcelVerifyDataGroupVerify(SdSchoolQuestionBankTestPaperVerify verify, String prefix) {LoginUser loginUser (LoginUser) SecurityUtils.getSubject().getPrincipal();boolean groupVerifySuccess true;if (verify null) {return groupVerifySuccess;}try {//校验成功成功返回true、失败返回falseString userId loginUser.getId();String key prefix userId;MapString, Object map new HashMap();map.put(xxxNo, verify.getTestPaperName().trim() verify.getXxxNo().trim());//有效期设置为30分钟long expireTime 30 * 60;SetOperations setOperations redisTemplate.opsForSet();setOperations.getOperations().expire(key, expireTime, TimeUnit.SECONDS);Set members setOperations.members(key);if (!members.contains(map)) {//如果不存在将数据缓存到redis中并设置有效期为30分钟当执行完导入操作之后删除缓存setOperations.add(key, map);} else {groupVerifySuccess false;}} catch (Exception e) {log.error(去重校验失败, e);}return groupVerifySuccess;}上面的方案总体来说是可以实现的只不过具体实现的时候出现了一些小毛病。 一眼看过去先设置过期时间再设置值这不是虚空设过期时间如果导入一条数据直接永不过期。不过一般导入的数量也不是一条按理说过半个小时应该能用才对。不过还是改了再说把设置过期时间的代码放到setOperations.add(key, map)下面。 接着查发现执行完业务代码之后只有成功才会删除key原来问题出在这。于是给异常后面加上一个finally在finally里面删除key这下无论你啥时候过期删除了就屁事没有。 测试环境验证一下。非常好没问题提测问题解决简简单单。 一波又起 到第二天业务反馈又出现一直处于导入中的情况。并且该账号半个小时以内并没有用过该excel导入。 奇怪了仔细又查了一遍代码不应该呀在finally里面有删除。无论如何肯定会执行删除操作呀。然后去看被限制人的导入半个小时内并没有导入。 上redis一看还真有缓存卧槽见鬼了。再去看半个小时内是否有导入还真有再细看过期时间和导入时间居然还对的上。 emm有情况。突然想到LoginUser的获取和ThreadLocal有点像会不会是异步导致的问题。于是本地启动去测用工具跑了很多次只用了一个账号。异步前后获取到的用户都是同一个于是认为LoginUser比ThreadLocal牛逼在异步的时候还会去提前更改盒子里的内容。其实是因为只有一个用户用来用去都只有一个用户各个线程里面存的都是该用户当然获取到的是一致的 灵光一闪 到第二天突然想到A导入却导致B被限制。那应该要多用户去测才对。于是更改测试方式结果获取到的结果显示异步前后获取到的LoginUser不一致。卧槽难崩原来是这个原因原来我猜想是对的。 因为新实现的导入都是直接用一个key作为判断是否存在正常导入的依据并且异步之后删除key用的也是通过传参传入的LoginUser而校验用的是ThreaLocal自然不会出现这种问题。 解决方案 那看来得改校验重复的实现方案了用我最喜欢的ThreadLocal。创建一个ThreadLocal静态变量这样里面存的数据都和线程相关异步之后一直是同一个线程自然不会出现错误的情况最后在finally里面清空ThreadLocal完美。 后续果然没有再出现过错误限制导入的情况。 原因分析 因为异步用到了线程池。请求进来的时候会校验用户信息并将用户信息存入LoginUser中以供全局使用。在线程执行结束之后线程回到线程池但线程对应的ThreadLocal的数据却没有清空。一般情况下如果都是走Controller进来的请求都不会有问题因为每次请求进来都会将新的用户信息set进去。但当异步的时候就没有set用户信息的过程线程内的用户信息还是上一次进入Controller用该线程的用户的用户信息。也就存在数据对不上的情况。而在异步中直接使用SecurityUtils.getSubject().getPrincipal()也就是犯了上面的错。 总的来说就是SecurityUtils.getSubject().getPrincipal()实际用的也是ThreadLocal而ThreadLocal和线程绑定异步会导致数据丢失注意
http://www.hkea.cn/news/14297013/

相关文章:

  • 做淘宝客要自己的网站番禺门户网站建设
  • 做网站的公司cnfg网站后端开发需要学什么
  • 顺义广州网站建设律师个人网站建设
  • 网站服务商排名网站建设租用服务器
  • 沛县建设局网站陈铭生小说
  • 重庆市工程建设信息网官方网站免费论坛创建
  • 怎么做html网站大理建设局网站
  • 基础型网站套餐哪个网站微博做的最好
  • 深圳网站建设排行安徽省住房和建设厅门户网站
  • 59一起做网站外贸企业网站制作
  • 晋城网站制作公司怎么选ztjs登录
  • wordpress搭建漫画站开发一个软件app需要多少钱
  • 崇州市微信端网站建时代强个人网站
  • 做网站公司排名运营网站需要多少钱
  • 网站如何加速移动网站开发百度百科
  • 手机免费做网站设计网站免费的
  • 可以做游戏的网站有哪些内容网站开发设计的完成情况
  • 提高网站的访问速度s001网站建设
  • 网站服务器分流怎么做神农架网站建设
  • 外网设计灵感网站seo上海推广公司
  • 网站开发所需要的的环境wordpress婚纱摄影主题
  • 上海建设官方网站塑胶托盘东莞网站建设
  • 橙米网站建设工业和信息化部icp网站备案系统
  • 搭建建立网站公司概况简介
  • 网站建设盒子怎么搭建国外主流网站开发技术
  • 徐州网站建设方案维护广州商城网站建设地址
  • 海尔网站的建设目标wordpress cms 插件
  • 嘉兴网站排名百度学术官网入口
  • 汉滨区建设局网网站班级网页制作
  • 常州网站支付通道建设做cpa推广用哪种网站好