Commit 96ecd5028dbf46e48cbb18bc61ae8ef40ba720c3
1 parent
44b0346e
1. 优化支付订单回调任务,避免重复打 SQL 查询日志
2. 修复定时任务的回调,回调成功未更新状态的问题。
Showing
5 changed files
with
21 additions
and
19 deletions
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoOrderController.java
| ... | ... | @@ -48,7 +48,7 @@ public class PayDemoOrderController { |
| 48 | 48 | } |
| 49 | 49 | |
| 50 | 50 | @PostMapping("/update-paid") |
| 51 | - @Operation(description = "更新示例订单为已支付") // 由 pay-module 支付服务,进行回调,可见 PayNotifyJob | |
| 51 | + @Operation(summary = "更新示例订单为已支付") // 由 pay-module 支付服务,进行回调,可见 PayNotifyJob | |
| 52 | 52 | @PermitAll // 无需登录,安全由 PayDemoOrderService 内部校验实现 |
| 53 | 53 | @OperateLog(enable = false) // 禁用操作日志,因为没有操作人 |
| 54 | 54 | public CommonResult<Boolean> updateDemoOrderPaid(@RequestBody PayOrderNotifyReqDTO notifyReqDTO) { |
| ... | ... | @@ -58,7 +58,7 @@ public class PayDemoOrderController { |
| 58 | 58 | } |
| 59 | 59 | |
| 60 | 60 | @PutMapping("/refund") |
| 61 | - @Operation(description = "发起示例订单的退款") | |
| 61 | + @Operation(summary = "发起示例订单的退款") | |
| 62 | 62 | @Parameter(name = "id", description = "编号", required = true, example = "1024") |
| 63 | 63 | public CommonResult<Boolean> refundDemoOrder(@RequestParam("id") Long id) { |
| 64 | 64 | payDemoOrderService.refundDemoOrder(id, getClientIP()); |
| ... | ... | @@ -66,7 +66,7 @@ public class PayDemoOrderController { |
| 66 | 66 | } |
| 67 | 67 | |
| 68 | 68 | @PostMapping("/update-refunded") |
| 69 | - @Operation(description = "更新示例订单为已退款") // 由 pay-module 支付服务,进行回调,可见 PayNotifyJob | |
| 69 | + @Operation(summary = "更新示例订单为已退款") // 由 pay-module 支付服务,进行回调,可见 PayNotifyJob | |
| 70 | 70 | @PermitAll // 无需登录,安全由 PayDemoOrderService 内部校验实现 |
| 71 | 71 | @OperateLog(enable = false) // 禁用操作日志,因为没有操作人 |
| 72 | 72 | public CommonResult<Boolean> updateDemoOrderRefunded(@RequestBody PayRefundNotifyReqDTO notifyReqDTO) { | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyLogCoreMapper.java renamed to yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyLogMapper.java
| ... | ... | @@ -5,5 +5,5 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| 5 | 5 | import org.apache.ibatis.annotations.Mapper; |
| 6 | 6 | |
| 7 | 7 | @Mapper |
| 8 | -public interface PayNotifyLogCoreMapper extends BaseMapperX<PayNotifyLogDO> { | |
| 8 | +public interface PayNotifyLogMapper extends BaseMapperX<PayNotifyLogDO> { | |
| 9 | 9 | } | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyTaskCoreMapper.java renamed to yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyTaskMapper.java
| ... | ... | @@ -10,7 +10,7 @@ import java.time.LocalDateTime; |
| 10 | 10 | import java.util.List; |
| 11 | 11 | |
| 12 | 12 | @Mapper |
| 13 | -public interface PayNotifyTaskCoreMapper extends BaseMapperX<PayNotifyTaskDO> { | |
| 13 | +public interface PayNotifyTaskMapper extends BaseMapperX<PayNotifyTaskDO> { | |
| 14 | 14 | |
| 15 | 15 | /** |
| 16 | 16 | * 获得需要通知的 PayNotifyTaskDO 记录。需要满足如下条件: | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/PayNotifyServiceImpl.java
| ... | ... | @@ -13,8 +13,8 @@ import cn.iocoder.yudao.module.pay.dal.dataobject.notify.PayNotifyLogDO; |
| 13 | 13 | import cn.iocoder.yudao.module.pay.dal.dataobject.notify.PayNotifyTaskDO; |
| 14 | 14 | import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; |
| 15 | 15 | import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO; |
| 16 | -import cn.iocoder.yudao.module.pay.dal.mysql.notify.PayNotifyLogCoreMapper; | |
| 17 | -import cn.iocoder.yudao.module.pay.dal.mysql.notify.PayNotifyTaskCoreMapper; | |
| 16 | +import cn.iocoder.yudao.module.pay.dal.mysql.notify.PayNotifyLogMapper; | |
| 17 | +import cn.iocoder.yudao.module.pay.dal.mysql.notify.PayNotifyTaskMapper; | |
| 18 | 18 | import cn.iocoder.yudao.module.pay.dal.redis.notify.PayNotifyLockRedisDAO; |
| 19 | 19 | import cn.iocoder.yudao.module.pay.enums.notify.PayNotifyStatusEnum; |
| 20 | 20 | import cn.iocoder.yudao.module.pay.enums.notify.PayNotifyTypeEnum; |
| ... | ... | @@ -32,6 +32,7 @@ import org.springframework.transaction.annotation.Transactional; |
| 32 | 32 | |
| 33 | 33 | import javax.annotation.Resource; |
| 34 | 34 | import javax.validation.Valid; |
| 35 | +import java.time.Duration; | |
| 35 | 36 | import java.time.LocalDateTime; |
| 36 | 37 | import java.util.HashMap; |
| 37 | 38 | import java.util.List; |
| ... | ... | @@ -40,6 +41,7 @@ import java.util.Objects; |
| 40 | 41 | import java.util.concurrent.CountDownLatch; |
| 41 | 42 | import java.util.concurrent.TimeUnit; |
| 42 | 43 | |
| 44 | +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*; | |
| 43 | 45 | import static cn.iocoder.yudao.module.pay.framework.job.config.PayJobConfiguration.NOTIFY_THREAD_POOL_TASK_EXECUTOR; |
| 44 | 46 | |
| 45 | 47 | /** |
| ... | ... | @@ -69,9 +71,9 @@ public class PayNotifyServiceImpl implements PayNotifyService { |
| 69 | 71 | private PayRefundService refundService; |
| 70 | 72 | |
| 71 | 73 | @Resource |
| 72 | - private PayNotifyTaskCoreMapper payNotifyTaskCoreMapper; | |
| 74 | + private PayNotifyTaskMapper payNotifyTaskMapper; | |
| 73 | 75 | @Resource |
| 74 | - private PayNotifyLogCoreMapper payNotifyLogCoreMapper; | |
| 76 | + private PayNotifyLogMapper payNotifyLogMapper; | |
| 75 | 77 | |
| 76 | 78 | @Resource(name = NOTIFY_THREAD_POOL_TASK_EXECUTOR) |
| 77 | 79 | private ThreadPoolTaskExecutor threadPoolTaskExecutor; |
| ... | ... | @@ -101,7 +103,7 @@ public class PayNotifyServiceImpl implements PayNotifyService { |
| 101 | 103 | } |
| 102 | 104 | |
| 103 | 105 | // 执行插入 |
| 104 | - payNotifyTaskCoreMapper.insert(task); | |
| 106 | + payNotifyTaskMapper.insert(task); | |
| 105 | 107 | |
| 106 | 108 | // 异步直接发起任务。虽然会有定时任务扫描,但是会导致延迟 |
| 107 | 109 | self.executeNotifyAsync(task); |
| ... | ... | @@ -110,7 +112,7 @@ public class PayNotifyServiceImpl implements PayNotifyService { |
| 110 | 112 | @Override |
| 111 | 113 | public int executeNotify() throws InterruptedException { |
| 112 | 114 | // 获得需要通知的任务 |
| 113 | - List<PayNotifyTaskDO> tasks = payNotifyTaskCoreMapper.selectListByNotify(); | |
| 115 | + List<PayNotifyTaskDO> tasks = payNotifyTaskMapper.selectListByNotify(); | |
| 114 | 116 | if (CollUtil.isEmpty(tasks)) { |
| 115 | 117 | return 0; |
| 116 | 118 | } |
| ... | ... | @@ -168,8 +170,8 @@ public class PayNotifyServiceImpl implements PayNotifyService { |
| 168 | 170 | payNotifyLockCoreRedisDAO.lock(task.getId(), NOTIFY_TIMEOUT_MILLIS, () -> { |
| 169 | 171 | // 校验,当前任务是否已经被通知过 |
| 170 | 172 | // 虽然已经通过分布式加锁,但是可能同时满足通知的条件,然后都去获得锁。此时,第一个执行完后,第二个还是能拿到锁,然后会再执行一次。 |
| 171 | - PayNotifyTaskDO dbTask = payNotifyTaskCoreMapper.selectById(task.getId()); | |
| 172 | - if (LocalDateTimeUtils.afterNow(dbTask.getNextNotifyTime())) { | |
| 173 | + PayNotifyTaskDO dbTask = payNotifyTaskMapper.selectById(task.getId()); | |
| 174 | + if (afterNow(dbTask.getNextNotifyTime())) { | |
| 173 | 175 | log.info("[executeNotifySync][dbTask({}) 任务被忽略,原因是未到达下次通知时间,可能是因为并发执行了]", |
| 174 | 176 | JsonUtils.toJsonString(dbTask)); |
| 175 | 177 | return; |
| ... | ... | @@ -197,7 +199,7 @@ public class PayNotifyServiceImpl implements PayNotifyService { |
| 197 | 199 | // 记录 PayNotifyLog 日志 |
| 198 | 200 | String response = invokeException != null ? ExceptionUtil.getRootCauseMessage(invokeException) : |
| 199 | 201 | JsonUtils.toJsonString(invokeResult); |
| 200 | - payNotifyLogCoreMapper.insert(PayNotifyLogDO.builder().taskId(task.getId()) | |
| 202 | + payNotifyLogMapper.insert(PayNotifyLogDO.builder().taskId(task.getId()) | |
| 201 | 203 | .notifyTimes(task.getNotifyTimes() + 1).status(newStatus).response(response).build()); |
| 202 | 204 | } |
| 203 | 205 | |
| ... | ... | @@ -250,23 +252,22 @@ public class PayNotifyServiceImpl implements PayNotifyService { |
| 250 | 252 | // 情况一:调用成功 |
| 251 | 253 | if (invokeResult != null && invokeResult.isSuccess()) { |
| 252 | 254 | updateTask.setStatus(PayNotifyStatusEnum.SUCCESS.getStatus()); |
| 255 | + payNotifyTaskMapper.updateById(updateTask); | |
| 253 | 256 | return updateTask.getStatus(); |
| 254 | 257 | } |
| 255 | 258 | // 情况二:调用失败、调用异常 |
| 256 | 259 | // 2.1 超过最大回调次数 |
| 257 | 260 | if (updateTask.getNotifyTimes() >= PayNotifyTaskDO.NOTIFY_FREQUENCY.length) { |
| 258 | 261 | updateTask.setStatus(PayNotifyStatusEnum.FAILURE.getStatus()); |
| 262 | + payNotifyTaskMapper.updateById(updateTask); | |
| 259 | 263 | return updateTask.getStatus(); |
| 260 | 264 | } |
| 261 | 265 | // 2.2 未超过最大回调次数 |
| 262 | - updateTask.setNextNotifyTime(LocalDateTime.now().plusSeconds(PayNotifyTaskDO.NOTIFY_FREQUENCY[updateTask.getNotifyTimes()])); | |
| 266 | + updateTask.setNextNotifyTime(addTime(Duration.ofSeconds(PayNotifyTaskDO.NOTIFY_FREQUENCY[updateTask.getNotifyTimes()]))); | |
| 263 | 267 | updateTask.setStatus(invokeException != null ? PayNotifyStatusEnum.REQUEST_FAILURE.getStatus() |
| 264 | 268 | : PayNotifyStatusEnum.REQUEST_SUCCESS.getStatus()); |
| 269 | + payNotifyTaskMapper.updateById(updateTask); | |
| 265 | 270 | return updateTask.getStatus(); |
| 266 | 271 | } |
| 267 | 272 | |
| 268 | - private void processNotifySuccess(PayNotifyTaskDO task, PayNotifyTaskDO updateTask) { | |
| 269 | - payNotifyTaskCoreMapper.updateById(updateTask); | |
| 270 | - } | |
| 271 | - | |
| 272 | 273 | } | ... | ... |
yudao-server/src/main/resources/application-local.yaml
| ... | ... | @@ -153,6 +153,7 @@ logging: |
| 153 | 153 | cn.iocoder.yudao.module.infra.dal.mysql: debug |
| 154 | 154 | cn.iocoder.yudao.module.infra.dal.mysql.job.JobLogMapper: INFO # 配置 JobLogMapper 的日志级别为 info |
| 155 | 155 | cn.iocoder.yudao.module.pay.dal.mysql: debug |
| 156 | + cn.iocoder.yudao.module.pay.dal.mysql.notify.PayNotifyTaskMapper: INFO # 配置 JobLogMapper 的日志级别为 info | |
| 156 | 157 | cn.iocoder.yudao.module.system.dal.mysql: debug |
| 157 | 158 | cn.iocoder.yudao.module.tool.dal.mysql: debug |
| 158 | 159 | cn.iocoder.yudao.module.member.dal.mysql: debug | ... | ... |