mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-10-30 09:48:43 +08:00 
			
		
		
		
	1. 优化支付订单回调任务,避免重复打 SQL 查询日志
2. 修复定时任务的回调,回调成功未更新状态的问题。
This commit is contained in:
		| @@ -48,7 +48,7 @@ public class PayDemoOrderController { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     @PostMapping("/update-paid") |     @PostMapping("/update-paid") | ||||||
|     @Operation(description = "更新示例订单为已支付") // 由 pay-module 支付服务,进行回调,可见 PayNotifyJob |     @Operation(summary = "更新示例订单为已支付") // 由 pay-module 支付服务,进行回调,可见 PayNotifyJob | ||||||
|     @PermitAll // 无需登录,安全由 PayDemoOrderService 内部校验实现 |     @PermitAll // 无需登录,安全由 PayDemoOrderService 内部校验实现 | ||||||
|     @OperateLog(enable = false) // 禁用操作日志,因为没有操作人 |     @OperateLog(enable = false) // 禁用操作日志,因为没有操作人 | ||||||
|     public CommonResult<Boolean> updateDemoOrderPaid(@RequestBody PayOrderNotifyReqDTO notifyReqDTO) { |     public CommonResult<Boolean> updateDemoOrderPaid(@RequestBody PayOrderNotifyReqDTO notifyReqDTO) { | ||||||
| @@ -58,7 +58,7 @@ public class PayDemoOrderController { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     @PutMapping("/refund") |     @PutMapping("/refund") | ||||||
|     @Operation(description = "发起示例订单的退款") |     @Operation(summary = "发起示例订单的退款") | ||||||
|     @Parameter(name = "id", description = "编号", required = true, example = "1024") |     @Parameter(name = "id", description = "编号", required = true, example = "1024") | ||||||
|     public CommonResult<Boolean> refundDemoOrder(@RequestParam("id") Long id) { |     public CommonResult<Boolean> refundDemoOrder(@RequestParam("id") Long id) { | ||||||
|         payDemoOrderService.refundDemoOrder(id, getClientIP()); |         payDemoOrderService.refundDemoOrder(id, getClientIP()); | ||||||
| @@ -66,7 +66,7 @@ public class PayDemoOrderController { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     @PostMapping("/update-refunded") |     @PostMapping("/update-refunded") | ||||||
|     @Operation(description = "更新示例订单为已退款") // 由 pay-module 支付服务,进行回调,可见 PayNotifyJob |     @Operation(summary = "更新示例订单为已退款") // 由 pay-module 支付服务,进行回调,可见 PayNotifyJob | ||||||
|     @PermitAll // 无需登录,安全由 PayDemoOrderService 内部校验实现 |     @PermitAll // 无需登录,安全由 PayDemoOrderService 内部校验实现 | ||||||
|     @OperateLog(enable = false) // 禁用操作日志,因为没有操作人 |     @OperateLog(enable = false) // 禁用操作日志,因为没有操作人 | ||||||
|     public CommonResult<Boolean> updateDemoOrderRefunded(@RequestBody PayRefundNotifyReqDTO notifyReqDTO) { |     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; | import org.apache.ibatis.annotations.Mapper; | ||||||
| 
 | 
 | ||||||
| @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; | import java.util.List; | ||||||
| 
 | 
 | ||||||
| @Mapper | @Mapper | ||||||
| public interface PayNotifyTaskCoreMapper extends BaseMapperX<PayNotifyTaskDO> { | public interface PayNotifyTaskMapper extends BaseMapperX<PayNotifyTaskDO> { | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * 获得需要通知的 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.notify.PayNotifyTaskDO; | ||||||
| import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; | 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.dataobject.refund.PayRefundDO; | ||||||
| import cn.iocoder.yudao.module.pay.dal.mysql.notify.PayNotifyLogCoreMapper; | import cn.iocoder.yudao.module.pay.dal.mysql.notify.PayNotifyLogMapper; | ||||||
| import cn.iocoder.yudao.module.pay.dal.mysql.notify.PayNotifyTaskCoreMapper; | 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.dal.redis.notify.PayNotifyLockRedisDAO; | ||||||
| import cn.iocoder.yudao.module.pay.enums.notify.PayNotifyStatusEnum; | import cn.iocoder.yudao.module.pay.enums.notify.PayNotifyStatusEnum; | ||||||
| import cn.iocoder.yudao.module.pay.enums.notify.PayNotifyTypeEnum; | 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.annotation.Resource; | ||||||
| import javax.validation.Valid; | import javax.validation.Valid; | ||||||
|  | import java.time.Duration; | ||||||
| import java.time.LocalDateTime; | import java.time.LocalDateTime; | ||||||
| import java.util.HashMap; | import java.util.HashMap; | ||||||
| import java.util.List; | import java.util.List; | ||||||
| @@ -40,6 +41,7 @@ import java.util.Objects; | |||||||
| import java.util.concurrent.CountDownLatch; | import java.util.concurrent.CountDownLatch; | ||||||
| import java.util.concurrent.TimeUnit; | 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; | 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; |     private PayRefundService refundService; | ||||||
|  |  | ||||||
|     @Resource |     @Resource | ||||||
|     private PayNotifyTaskCoreMapper payNotifyTaskCoreMapper; |     private PayNotifyTaskMapper payNotifyTaskMapper; | ||||||
|     @Resource |     @Resource | ||||||
|     private PayNotifyLogCoreMapper payNotifyLogCoreMapper; |     private PayNotifyLogMapper payNotifyLogMapper; | ||||||
|  |  | ||||||
|     @Resource(name = NOTIFY_THREAD_POOL_TASK_EXECUTOR) |     @Resource(name = NOTIFY_THREAD_POOL_TASK_EXECUTOR) | ||||||
|     private ThreadPoolTaskExecutor threadPoolTaskExecutor; |     private ThreadPoolTaskExecutor threadPoolTaskExecutor; | ||||||
| @@ -101,7 +103,7 @@ public class PayNotifyServiceImpl implements PayNotifyService { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         // 执行插入 |         // 执行插入 | ||||||
|         payNotifyTaskCoreMapper.insert(task); |         payNotifyTaskMapper.insert(task); | ||||||
|  |  | ||||||
|         // 异步直接发起任务。虽然会有定时任务扫描,但是会导致延迟 |         // 异步直接发起任务。虽然会有定时任务扫描,但是会导致延迟 | ||||||
|         self.executeNotifyAsync(task); |         self.executeNotifyAsync(task); | ||||||
| @@ -110,7 +112,7 @@ public class PayNotifyServiceImpl implements PayNotifyService { | |||||||
|     @Override |     @Override | ||||||
|     public int executeNotify() throws InterruptedException { |     public int executeNotify() throws InterruptedException { | ||||||
|         // 获得需要通知的任务 |         // 获得需要通知的任务 | ||||||
|         List<PayNotifyTaskDO> tasks = payNotifyTaskCoreMapper.selectListByNotify(); |         List<PayNotifyTaskDO> tasks = payNotifyTaskMapper.selectListByNotify(); | ||||||
|         if (CollUtil.isEmpty(tasks)) { |         if (CollUtil.isEmpty(tasks)) { | ||||||
|             return 0; |             return 0; | ||||||
|         } |         } | ||||||
| @@ -168,8 +170,8 @@ public class PayNotifyServiceImpl implements PayNotifyService { | |||||||
|         payNotifyLockCoreRedisDAO.lock(task.getId(), NOTIFY_TIMEOUT_MILLIS, () -> { |         payNotifyLockCoreRedisDAO.lock(task.getId(), NOTIFY_TIMEOUT_MILLIS, () -> { | ||||||
|             // 校验,当前任务是否已经被通知过 |             // 校验,当前任务是否已经被通知过 | ||||||
|             // 虽然已经通过分布式加锁,但是可能同时满足通知的条件,然后都去获得锁。此时,第一个执行完后,第二个还是能拿到锁,然后会再执行一次。 |             // 虽然已经通过分布式加锁,但是可能同时满足通知的条件,然后都去获得锁。此时,第一个执行完后,第二个还是能拿到锁,然后会再执行一次。 | ||||||
|             PayNotifyTaskDO dbTask = payNotifyTaskCoreMapper.selectById(task.getId()); |             PayNotifyTaskDO dbTask = payNotifyTaskMapper.selectById(task.getId()); | ||||||
|             if (LocalDateTimeUtils.afterNow(dbTask.getNextNotifyTime())) { |             if (afterNow(dbTask.getNextNotifyTime())) { | ||||||
|                 log.info("[executeNotifySync][dbTask({}) 任务被忽略,原因是未到达下次通知时间,可能是因为并发执行了]", |                 log.info("[executeNotifySync][dbTask({}) 任务被忽略,原因是未到达下次通知时间,可能是因为并发执行了]", | ||||||
|                         JsonUtils.toJsonString(dbTask)); |                         JsonUtils.toJsonString(dbTask)); | ||||||
|                 return; |                 return; | ||||||
| @@ -197,7 +199,7 @@ public class PayNotifyServiceImpl implements PayNotifyService { | |||||||
|         // 记录 PayNotifyLog 日志 |         // 记录 PayNotifyLog 日志 | ||||||
|         String response = invokeException != null ? ExceptionUtil.getRootCauseMessage(invokeException) : |         String response = invokeException != null ? ExceptionUtil.getRootCauseMessage(invokeException) : | ||||||
|                 JsonUtils.toJsonString(invokeResult); |                 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()); |                 .notifyTimes(task.getNotifyTimes() + 1).status(newStatus).response(response).build()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -250,23 +252,22 @@ public class PayNotifyServiceImpl implements PayNotifyService { | |||||||
|         // 情况一:调用成功 |         // 情况一:调用成功 | ||||||
|         if (invokeResult != null && invokeResult.isSuccess()) { |         if (invokeResult != null && invokeResult.isSuccess()) { | ||||||
|             updateTask.setStatus(PayNotifyStatusEnum.SUCCESS.getStatus()); |             updateTask.setStatus(PayNotifyStatusEnum.SUCCESS.getStatus()); | ||||||
|  |             payNotifyTaskMapper.updateById(updateTask); | ||||||
|             return updateTask.getStatus(); |             return updateTask.getStatus(); | ||||||
|         } |         } | ||||||
|         // 情况二:调用失败、调用异常 |         // 情况二:调用失败、调用异常 | ||||||
|         // 2.1 超过最大回调次数 |         // 2.1 超过最大回调次数 | ||||||
|         if (updateTask.getNotifyTimes() >= PayNotifyTaskDO.NOTIFY_FREQUENCY.length) { |         if (updateTask.getNotifyTimes() >= PayNotifyTaskDO.NOTIFY_FREQUENCY.length) { | ||||||
|             updateTask.setStatus(PayNotifyStatusEnum.FAILURE.getStatus()); |             updateTask.setStatus(PayNotifyStatusEnum.FAILURE.getStatus()); | ||||||
|  |             payNotifyTaskMapper.updateById(updateTask); | ||||||
|             return updateTask.getStatus(); |             return updateTask.getStatus(); | ||||||
|         } |         } | ||||||
|         // 2.2 未超过最大回调次数 |         // 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() |         updateTask.setStatus(invokeException != null ? PayNotifyStatusEnum.REQUEST_FAILURE.getStatus() | ||||||
|                 : PayNotifyStatusEnum.REQUEST_SUCCESS.getStatus()); |                 : PayNotifyStatusEnum.REQUEST_SUCCESS.getStatus()); | ||||||
|  |         payNotifyTaskMapper.updateById(updateTask); | ||||||
|         return updateTask.getStatus(); |         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: debug | ||||||
|     cn.iocoder.yudao.module.infra.dal.mysql.job.JobLogMapper: INFO # 配置 JobLogMapper 的日志级别为 info |     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: 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.system.dal.mysql: debug | ||||||
|     cn.iocoder.yudao.module.tool.dal.mysql: debug |     cn.iocoder.yudao.module.tool.dal.mysql: debug | ||||||
|     cn.iocoder.yudao.module.member.dal.mysql: debug |     cn.iocoder.yudao.module.member.dal.mysql: debug | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 YunaiV
					YunaiV