From 89cf7bfdfd23d55fae47c7e2cf5f9ee9f4a2bcbb Mon Sep 17 00:00:00 2001
From: Administrator <15274802129@163.com>
Date: Mon, 21 Sep 2026 09:52:58 +0800
Subject: [PATCH] ``` fix(gateApi): 修复网格交易队列生成的并发安全问题
---
src/main/java/com/xcong/excoin/modules/gateApi/GateTradeExecutor.java | 52 +++++++++++++++++++++++++++++++++++++++++-----------
1 files changed, 41 insertions(+), 11 deletions(-)
diff --git a/src/main/java/com/xcong/excoin/modules/gateApi/GateTradeExecutor.java b/src/main/java/com/xcong/excoin/modules/gateApi/GateTradeExecutor.java
index 9984cf9..e638112 100644
--- a/src/main/java/com/xcong/excoin/modules/gateApi/GateTradeExecutor.java
+++ b/src/main/java/com/xcong/excoin/modules/gateApi/GateTradeExecutor.java
@@ -54,6 +54,11 @@
private static final String SETTLE = "usdt";
+ /** 止盈/止损条件单创建失败后的重试次数 */
+ private static final int TRIGGER_ORDER_RETRY_MAX_ATTEMPTS = 3;
+ /** 止盈/止损条件单创建失败后的重试间隔(毫秒) */
+ private static final long TRIGGER_ORDER_RETRY_DELAY_MS = 500L;
+
/** Gate U 本位合约 REST API */
private final FuturesApi futuresApi;
/** 合约名称(如 ETH_USDT) */
@@ -91,6 +96,13 @@
Thread.currentThread().interrupt();
executor.shutdownNow();
}
+ }
+ /**
+ * 提交一个通用任务到交易线程池末尾。
+ * 利用单线程池的 FIFO 特性确保任务按提交顺序执行。
+ */
+ public void submitTask(Runnable task) {
+ executor.execute(task);
}
/**
@@ -172,17 +184,32 @@
Consumer<String> onSuccess) {
executor.execute(() -> {
FuturesPriceTriggeredOrder order = buildTriggeredOrder(triggerPrice, rule, orderType, size);
- try {
- TriggerOrderResponse response = futuresApi.createPriceTriggeredOrder(SETTLE, order);
- log.info("[TradeExec] 止盈单已创建, 触发价:{}, 类型:{}, size:{}, id:{},idstr:{}",
- triggerPrice, orderType, size, response.getId(), response.getIdString());
- String orderId = String.valueOf(response.getId());
- if (onSuccess != null) {
- onSuccess.accept(orderId);
+ for (int attempt = 1; attempt <= TRIGGER_ORDER_RETRY_MAX_ATTEMPTS; attempt++) {
+ try {
+ TriggerOrderResponse response = futuresApi.createPriceTriggeredOrder(SETTLE, order);
+ log.info("[TradeExec] 止盈单已创建, 触发价:{}, 类型:{}, size:{}, id:{},idstr:{}",
+ triggerPrice, orderType, size, response.getId(), response.getIdString());
+ String orderId = String.valueOf(response.getId());
+ if (onSuccess != null) {
+ onSuccess.accept(orderId);
+ }
+ return;
+ } catch (Exception e) {
+ if (attempt < TRIGGER_ORDER_RETRY_MAX_ATTEMPTS) {
+ log.warn("[TradeExec] 止盈单创建失败, 触发价:{}, size:{}, 第{}次尝试失败, {}ms后重试, err:{}",
+ triggerPrice, size, attempt, TRIGGER_ORDER_RETRY_DELAY_MS, e.getMessage());
+ try {
+ Thread.sleep(TRIGGER_ORDER_RETRY_DELAY_MS);
+ } catch (InterruptedException ie) {
+ Thread.currentThread().interrupt();
+ marketClose(size);
+ return;
+ }
+ } else {
+ log.error("[TradeExec] 止盈单创建失败, 触发价:{}, size:{}, 立即市价止盈", triggerPrice, size, e);
+ marketClose(size);
+ }
}
- } catch (Exception e) {
- log.error("[TradeExec] 止盈单创建失败, 触发价:{}, size:{}, 立即市价止盈", triggerPrice, size, e);
- marketClose(size);
}
});
}
@@ -338,7 +365,7 @@
*
* @param orderId 条件单 ID,为 null 时跳过
*/
- public void cancelConditionalOrder(String orderId) {
+ public void cancelConditionalOrder(String orderId,Consumer<String> onSuccess) {
if (orderId == null) {
return;
}
@@ -346,6 +373,9 @@
try {
futuresApi.cancelPriceTriggeredOrder(SETTLE, Long.parseLong(orderId));
log.info("[TradeExec] 条件单已取消, id:{}", orderId);
+ if (onSuccess != null) {
+ onSuccess.accept(orderId);
+ }
} catch (Exception e) {
log.warn("[TradeExec] 取消条件单失败(可能已触发), id:{}", orderId);
}
--
Gitblit v1.9.1