From 96ecd5028dbf46e48cbb18bc61ae8ef40ba720c3 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 16 Feb 2023 23:54:23 +0800 Subject: [PATCH] 1. 优化支付订单回调任务,避免重复打 SQL 查询日志 2. 修复定时任务的回调,回调成功未更新状态的问题。 --- yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoOrderController.java | 6 +++--- yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyLogCoreMapper.java | 9 --------- yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyLogMapper.java | 9 +++++++++ yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyTaskCoreMapper.java | 30 ------------------------------ yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyTaskMapper.java | 30 ++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/PayNotifyServiceImpl.java | 29 +++++++++++++++-------------- yudao-server/src/main/resources/application-local.yaml | 1 + 7 files changed, 58 insertions(+), 56 deletions(-) delete mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyLogCoreMapper.java create mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyLogMapper.java delete mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyTaskCoreMapper.java create mode 100644 yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyTaskMapper.java diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoOrderController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoOrderController.java index 41a7ffd..1e3a61e 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoOrderController.java +++ b/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 { } @PostMapping("/update-paid") - @Operation(description = "更新示例订单为已支付") // 由 pay-module 支付服务,进行回调,可见 PayNotifyJob + @Operation(summary = "更新示例订单为已支付") // 由 pay-module 支付服务,进行回调,可见 PayNotifyJob @PermitAll // 无需登录,安全由 PayDemoOrderService 内部校验实现 @OperateLog(enable = false) // 禁用操作日志,因为没有操作人 public CommonResult updateDemoOrderPaid(@RequestBody PayOrderNotifyReqDTO notifyReqDTO) { @@ -58,7 +58,7 @@ public class PayDemoOrderController { } @PutMapping("/refund") - @Operation(description = "发起示例订单的退款") + @Operation(summary = "发起示例订单的退款") @Parameter(name = "id", description = "编号", required = true, example = "1024") public CommonResult refundDemoOrder(@RequestParam("id") Long id) { payDemoOrderService.refundDemoOrder(id, getClientIP()); @@ -66,7 +66,7 @@ public class PayDemoOrderController { } @PostMapping("/update-refunded") - @Operation(description = "更新示例订单为已退款") // 由 pay-module 支付服务,进行回调,可见 PayNotifyJob + @Operation(summary = "更新示例订单为已退款") // 由 pay-module 支付服务,进行回调,可见 PayNotifyJob @PermitAll // 无需登录,安全由 PayDemoOrderService 内部校验实现 @OperateLog(enable = false) // 禁用操作日志,因为没有操作人 public CommonResult updateDemoOrderRefunded(@RequestBody PayRefundNotifyReqDTO notifyReqDTO) { diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyLogCoreMapper.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyLogCoreMapper.java deleted file mode 100644 index c956219..0000000 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyLogCoreMapper.java +++ /dev/null @@ -1,9 +0,0 @@ -package cn.iocoder.yudao.module.pay.dal.mysql.notify; - -import cn.iocoder.yudao.module.pay.dal.dataobject.notify.PayNotifyLogDO; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import org.apache.ibatis.annotations.Mapper; - -@Mapper -public interface PayNotifyLogCoreMapper extends BaseMapperX { -} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyLogMapper.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyLogMapper.java new file mode 100644 index 0000000..34a7b62 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyLogMapper.java @@ -0,0 +1,9 @@ +package cn.iocoder.yudao.module.pay.dal.mysql.notify; + +import cn.iocoder.yudao.module.pay.dal.dataobject.notify.PayNotifyLogDO; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface PayNotifyLogMapper extends BaseMapperX { +} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyTaskCoreMapper.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyTaskCoreMapper.java deleted file mode 100644 index ca876a3..0000000 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyTaskCoreMapper.java +++ /dev/null @@ -1,30 +0,0 @@ -package cn.iocoder.yudao.module.pay.dal.mysql.notify; - -import cn.iocoder.yudao.module.pay.dal.dataobject.notify.PayNotifyTaskDO; -import cn.iocoder.yudao.module.pay.enums.notify.PayNotifyStatusEnum; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import org.apache.ibatis.annotations.Mapper; - -import java.time.LocalDateTime; -import java.util.List; - -@Mapper -public interface PayNotifyTaskCoreMapper extends BaseMapperX { - - /** - * 获得需要通知的 PayNotifyTaskDO 记录。需要满足如下条件: - * - * 1. status 非成功 - * 2. nextNotifyTime 小于当前时间 - * - * @return PayTransactionNotifyTaskDO 数组 - */ - default List selectListByNotify() { - return selectList(new QueryWrapper() - .in("status", PayNotifyStatusEnum.WAITING.getStatus(), PayNotifyStatusEnum.REQUEST_SUCCESS.getStatus(), - PayNotifyStatusEnum.REQUEST_FAILURE.getStatus()) - .le("next_notify_time", LocalDateTime.now())); - } - -} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyTaskMapper.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyTaskMapper.java new file mode 100644 index 0000000..37ec65a --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyTaskMapper.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.pay.dal.mysql.notify; + +import cn.iocoder.yudao.module.pay.dal.dataobject.notify.PayNotifyTaskDO; +import cn.iocoder.yudao.module.pay.enums.notify.PayNotifyStatusEnum; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import org.apache.ibatis.annotations.Mapper; + +import java.time.LocalDateTime; +import java.util.List; + +@Mapper +public interface PayNotifyTaskMapper extends BaseMapperX { + + /** + * 获得需要通知的 PayNotifyTaskDO 记录。需要满足如下条件: + * + * 1. status 非成功 + * 2. nextNotifyTime 小于当前时间 + * + * @return PayTransactionNotifyTaskDO 数组 + */ + default List selectListByNotify() { + return selectList(new QueryWrapper() + .in("status", PayNotifyStatusEnum.WAITING.getStatus(), PayNotifyStatusEnum.REQUEST_SUCCESS.getStatus(), + PayNotifyStatusEnum.REQUEST_FAILURE.getStatus()) + .le("next_notify_time", LocalDateTime.now())); + } + +} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/PayNotifyServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/PayNotifyServiceImpl.java index 1f81312..d0c525b 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/notify/PayNotifyServiceImpl.java +++ b/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; import cn.iocoder.yudao.module.pay.dal.dataobject.notify.PayNotifyTaskDO; import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO; -import cn.iocoder.yudao.module.pay.dal.mysql.notify.PayNotifyLogCoreMapper; -import cn.iocoder.yudao.module.pay.dal.mysql.notify.PayNotifyTaskCoreMapper; +import cn.iocoder.yudao.module.pay.dal.mysql.notify.PayNotifyLogMapper; +import cn.iocoder.yudao.module.pay.dal.mysql.notify.PayNotifyTaskMapper; import cn.iocoder.yudao.module.pay.dal.redis.notify.PayNotifyLockRedisDAO; import cn.iocoder.yudao.module.pay.enums.notify.PayNotifyStatusEnum; import cn.iocoder.yudao.module.pay.enums.notify.PayNotifyTypeEnum; @@ -32,6 +32,7 @@ import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import javax.validation.Valid; +import java.time.Duration; import java.time.LocalDateTime; import java.util.HashMap; import java.util.List; @@ -40,6 +41,7 @@ import java.util.Objects; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*; import static cn.iocoder.yudao.module.pay.framework.job.config.PayJobConfiguration.NOTIFY_THREAD_POOL_TASK_EXECUTOR; /** @@ -69,9 +71,9 @@ public class PayNotifyServiceImpl implements PayNotifyService { private PayRefundService refundService; @Resource - private PayNotifyTaskCoreMapper payNotifyTaskCoreMapper; + private PayNotifyTaskMapper payNotifyTaskMapper; @Resource - private PayNotifyLogCoreMapper payNotifyLogCoreMapper; + private PayNotifyLogMapper payNotifyLogMapper; @Resource(name = NOTIFY_THREAD_POOL_TASK_EXECUTOR) private ThreadPoolTaskExecutor threadPoolTaskExecutor; @@ -101,7 +103,7 @@ public class PayNotifyServiceImpl implements PayNotifyService { } // 执行插入 - payNotifyTaskCoreMapper.insert(task); + payNotifyTaskMapper.insert(task); // 异步直接发起任务。虽然会有定时任务扫描,但是会导致延迟 self.executeNotifyAsync(task); @@ -110,7 +112,7 @@ public class PayNotifyServiceImpl implements PayNotifyService { @Override public int executeNotify() throws InterruptedException { // 获得需要通知的任务 - List tasks = payNotifyTaskCoreMapper.selectListByNotify(); + List tasks = payNotifyTaskMapper.selectListByNotify(); if (CollUtil.isEmpty(tasks)) { return 0; } @@ -168,8 +170,8 @@ public class PayNotifyServiceImpl implements PayNotifyService { payNotifyLockCoreRedisDAO.lock(task.getId(), NOTIFY_TIMEOUT_MILLIS, () -> { // 校验,当前任务是否已经被通知过 // 虽然已经通过分布式加锁,但是可能同时满足通知的条件,然后都去获得锁。此时,第一个执行完后,第二个还是能拿到锁,然后会再执行一次。 - PayNotifyTaskDO dbTask = payNotifyTaskCoreMapper.selectById(task.getId()); - if (LocalDateTimeUtils.afterNow(dbTask.getNextNotifyTime())) { + PayNotifyTaskDO dbTask = payNotifyTaskMapper.selectById(task.getId()); + if (afterNow(dbTask.getNextNotifyTime())) { log.info("[executeNotifySync][dbTask({}) 任务被忽略,原因是未到达下次通知时间,可能是因为并发执行了]", JsonUtils.toJsonString(dbTask)); return; @@ -197,7 +199,7 @@ public class PayNotifyServiceImpl implements PayNotifyService { // 记录 PayNotifyLog 日志 String response = invokeException != null ? ExceptionUtil.getRootCauseMessage(invokeException) : JsonUtils.toJsonString(invokeResult); - payNotifyLogCoreMapper.insert(PayNotifyLogDO.builder().taskId(task.getId()) + payNotifyLogMapper.insert(PayNotifyLogDO.builder().taskId(task.getId()) .notifyTimes(task.getNotifyTimes() + 1).status(newStatus).response(response).build()); } @@ -250,23 +252,22 @@ public class PayNotifyServiceImpl implements PayNotifyService { // 情况一:调用成功 if (invokeResult != null && invokeResult.isSuccess()) { updateTask.setStatus(PayNotifyStatusEnum.SUCCESS.getStatus()); + payNotifyTaskMapper.updateById(updateTask); return updateTask.getStatus(); } // 情况二:调用失败、调用异常 // 2.1 超过最大回调次数 if (updateTask.getNotifyTimes() >= PayNotifyTaskDO.NOTIFY_FREQUENCY.length) { updateTask.setStatus(PayNotifyStatusEnum.FAILURE.getStatus()); + payNotifyTaskMapper.updateById(updateTask); return updateTask.getStatus(); } // 2.2 未超过最大回调次数 - updateTask.setNextNotifyTime(LocalDateTime.now().plusSeconds(PayNotifyTaskDO.NOTIFY_FREQUENCY[updateTask.getNotifyTimes()])); + updateTask.setNextNotifyTime(addTime(Duration.ofSeconds(PayNotifyTaskDO.NOTIFY_FREQUENCY[updateTask.getNotifyTimes()]))); updateTask.setStatus(invokeException != null ? PayNotifyStatusEnum.REQUEST_FAILURE.getStatus() : PayNotifyStatusEnum.REQUEST_SUCCESS.getStatus()); + payNotifyTaskMapper.updateById(updateTask); return updateTask.getStatus(); } - private void processNotifySuccess(PayNotifyTaskDO task, PayNotifyTaskDO updateTask) { - payNotifyTaskCoreMapper.updateById(updateTask); - } - } diff --git a/yudao-server/src/main/resources/application-local.yaml b/yudao-server/src/main/resources/application-local.yaml index 2c8204b..6c804b0 100644 --- a/yudao-server/src/main/resources/application-local.yaml +++ b/yudao-server/src/main/resources/application-local.yaml @@ -153,6 +153,7 @@ logging: cn.iocoder.yudao.module.infra.dal.mysql: debug cn.iocoder.yudao.module.infra.dal.mysql.job.JobLogMapper: INFO # 配置 JobLogMapper 的日志级别为 info cn.iocoder.yudao.module.pay.dal.mysql: debug + cn.iocoder.yudao.module.pay.dal.mysql.notify.PayNotifyTaskMapper: INFO # 配置 JobLogMapper 的日志级别为 info cn.iocoder.yudao.module.system.dal.mysql: debug cn.iocoder.yudao.module.tool.dal.mysql: debug cn.iocoder.yudao.module.member.dal.mysql: debug -- libgit2 0.21.4