mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-10-31 02:08:43 +08:00 
			
		
		
		
	1. 优化支付订单回调任务,避免重复打 SQL 查询日志
2. 修复定时任务的回调,回调成功未更新状态的问题。
This commit is contained in:
		| @@ -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<Boolean> 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<Boolean> 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<Boolean> updateDemoOrderRefunded(@RequestBody PayRefundNotifyReqDTO notifyReqDTO) { | ||||
|   | ||||
| @@ -5,5 +5,5 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | ||||
| import org.apache.ibatis.annotations.Mapper; | ||||
| 
 | ||||
| @Mapper | ||||
| public interface PayNotifyLogCoreMapper extends BaseMapperX<PayNotifyLogDO> { | ||||
| public interface PayNotifyLogMapper extends BaseMapperX<PayNotifyLogDO> { | ||||
| } | ||||
| @@ -10,7 +10,7 @@ import java.time.LocalDateTime; | ||||
| import java.util.List; | ||||
| 
 | ||||
| @Mapper | ||||
| public interface PayNotifyTaskCoreMapper extends BaseMapperX<PayNotifyTaskDO> { | ||||
| public interface PayNotifyTaskMapper extends BaseMapperX<PayNotifyTaskDO> { | ||||
| 
 | ||||
|     /** | ||||
|      * 获得需要通知的 PayNotifyTaskDO 记录。需要满足如下条件: | ||||
| @@ -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<PayNotifyTaskDO> tasks = payNotifyTaskCoreMapper.selectListByNotify(); | ||||
|         List<PayNotifyTaskDO> 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); | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 YunaiV
					YunaiV