记录一次,事务遇到消息发送,疏忽给自己挖坑
时间:2019-06-12
本文章向大家介绍记录一次,事务遇到消息发送,疏忽给自己挖坑,主要包括记录一次,事务遇到消息发送,疏忽给自己挖坑使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
场景:一个异步重算功能(任务新建后发送消息到RocketMq),每次重算单条记录的时候,可以计算正确,但是当多条记录批量重算时,结果总是莫名其妙的不对。排查了很久,终于找到原因
原因:在新建重算任务方法上添加了事务注解,而发送消息也在该方法中,导致事务未提交,消息已经发出去了。
源代码:
@Transactional public void updateGiftCostByTradeList(ShopShard shopShard, List<Trade> tradeList) { Preconditions.checkArgument(null != shopShard && !CollectionUtils.isEmpty(tradeList)); for (Trade trade : tradeList) { if (TradeSpecialTypeEnum.getSpecialTypes().contains(trade.getTradeSpecialType())) { continue; } long giftCost = getGiftCostFromZhanggui(shopShard.getShopId(), trade); giftCost = giftCost > 0 ? giftCost : getGiftCostFromCaiwu(shopShard.getShopId(), trade); if ((trade.getGiftFee() == null ? 0 : trade.getGiftFee()) == giftCost) { continue; } tradeService.updateTradeGiftFee(shopShard.getShopId(), trade.getId(), giftCost); SendMsgToMqUtil.sendTradeMsgToTradeFeeTopic(rocketMqProducer, shopShard, trade); } }
更改后:
@Transactional public void updateGiftCostByTradeList(ShopShard shopShard, List<Trade> tradeList) { Preconditions.checkArgument(null != shopShard && !CollectionUtils.isEmpty(tradeList)); for (Trade trade : tradeList) { if (TradeSpecialTypeEnum.getSpecialTypes().contains(trade.getTradeSpecialType())) { continue; } long giftCost = getGiftCostFromZhanggui(shopShard.getShopId(), trade); giftCost = giftCost > 0 ? giftCost : getGiftCostFromCaiwu(shopShard.getShopId(), trade); if ((trade.getGiftFee() == null ? 0 : trade.getGiftFee()) == giftCost) { continue; } tradeService.updateTradeGiftFee(shopShard.getShopId(), trade.getId(), giftCost); } } private void doProcessCostRule(ShopShard shopShard, CostRule costRule) {
commonCostRuleService.updateGiftCostByTradeList(shopShard, pageInfo.getList());
pageInfo.getList().forEach(trade -> {
if (!recalStatPoolCommonServcie.sendMqToRecalStatPoolByTrade(trade, TradeStatRecalSourceEnum.GIFT_COST)) {
log.error("process costRule trade send recalstatpool false shopId={}|trade={}", shopShard.getShopId(), JSON.toJSONString(trade));
}
});
}
原文地址:https://www.cnblogs.com/JoeyWong/p/11011294.html
- linux运维中的命令梳理(四)
- linux运维中的命令梳理(三)
- 轻松水印-批量提取exif信息加水印的工具
- Enterprise Library 4.1学习笔记7----缓存应用程序块之SqlDependency
- linux运维中的命令梳理(一)
- 可视化你的BLAST结果
- linux运维中的命令梳理(二)
- VB-取日期属于星期几
- 全球AI新闻创新实践系列③:华邮、雅虎、美联社、Quartz怎么干!
- nginx+php负载均衡集群环境中的session共享方案梳理
- PowerPoint发布及链接图片的处理
- EXCEL单元格的引用方式
- SqlDependency学习笔记
- linux系统下对网站实施负载均衡+高可用集群需要考虑的几点
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- PHP Multipart/form-data remote DOS 防御方案研究
- Kubernetes Python Client
- 对JiaThis Flash XSS的挖掘与分析
- Spark 3.0.1 Structured Streaming 提交程序异常解决
- 一起来探索下小程序包的魔数
- 新浪微博IPAD客户端XSS(file域) + 构造Worm
- Firefox 31~34远程命令执行漏洞的分析
- emlog绕过验证码刷评论
- cmseasy最新注入+360webscan的绕过分析
- 新型任意文件读取漏洞的研究
- Chrome XSS Auditor Bypass Using SVG
- ngx_lua_waf针对性改写
- Wordpress < 4.1.2 存储型XSS分析与稳定POC
- 重构Sec-News之路
- ThinkPHP留后门技巧