From 3e2e97e5729723e14dd4f42cec4a5b02cb8c3684 Mon Sep 17 00:00:00 2001 From: WrBug Date: Fri, 16 Jan 2026 10:28:39 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20CopyOrderTrackingSe?= =?UTF-8?q?rvice=20=E5=92=8C=20CopyTradingService=20=E7=9A=84=20@Transacti?= =?UTF-8?q?onal=20=E8=87=AA=E8=B0=83=E7=94=A8=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. CopyOrderTrackingService 修复 - 实现 ApplicationContextAware 接口 - 添加 getSelf() 方法获取代理对象 - 在 processTrade() 中通过代理调用 processBuyTrade() 和 processSellTrade() - 确保两个子方法的 @Transactional 生效 2. CopyTradingService 修复 - 实现 ApplicationContextAware 接口 - 添加 getSelf() 方法获取代理对象 - 在 updateCopyTradingStatus() 中通过代理调用 updateCopyTrading() - 确保内部调用的 @Transactional 生效 修改的文件: - CopyOrderTrackingService.kt - CopyTradingService.kt --- .../copytrading/configs/CopyTradingService.kt | 22 +++++++++++++--- .../statistics/CopyOrderTrackingService.kt | 25 ++++++++++++++++--- 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/configs/CopyTradingService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/configs/CopyTradingService.kt index e66e434..e238a3a 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/configs/CopyTradingService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/configs/CopyTradingService.kt @@ -14,6 +14,8 @@ import com.wrbug.polymarketbot.util.IllegalBigDecimal import com.wrbug.polymarketbot.util.JsonUtils import com.wrbug.polymarketbot.util.toSafeBigDecimal import org.slf4j.LoggerFactory +import org.springframework.context.ApplicationContext +import org.springframework.context.ApplicationContextAware import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional import java.math.BigDecimal @@ -30,10 +32,24 @@ class CopyTradingService( private val monitorService: CopyTradingMonitorService, private val jsonUtils: JsonUtils, private val gson: Gson -) { - +) : ApplicationContextAware { + private val logger = LoggerFactory.getLogger(CopyTradingService::class.java) + private var applicationContext: ApplicationContext? = null + + override fun setApplicationContext(applicationContext: ApplicationContext) { + this.applicationContext = applicationContext + } + + /** + * 获取代理对象,用于解决 @Transactional 自调用问题 + */ + private fun getSelf(): CopyTradingService { + return applicationContext?.getBean(CopyTradingService::class.java) + ?: throw IllegalStateException("ApplicationContext not initialized") + } + /** * 创建跟单配置 * 支持两种方式: @@ -331,7 +347,7 @@ class CopyTradingService( */ @Transactional fun updateCopyTradingStatus(request: CopyTradingUpdateStatusRequest): Result { - return updateCopyTrading( + return getSelf().updateCopyTrading( CopyTradingUpdateRequest( copyTradingId = request.copyTradingId, enabled = request.enabled diff --git a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/statistics/CopyOrderTrackingService.kt b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/statistics/CopyOrderTrackingService.kt index 5f300bc..49ee84f 100644 --- a/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/statistics/CopyOrderTrackingService.kt +++ b/backend/src/main/kotlin/com/wrbug/polymarketbot/service/copytrading/statistics/CopyOrderTrackingService.kt @@ -23,6 +23,8 @@ import com.wrbug.polymarketbot.service.common.MarketService import com.wrbug.polymarketbot.service.common.PolymarketClobService import com.wrbug.polymarketbot.service.system.TelegramNotificationService import com.wrbug.polymarketbot.util.CryptoUtils +import org.springframework.context.ApplicationContext +import org.springframework.context.ApplicationContextAware import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional import java.math.BigDecimal @@ -51,12 +53,26 @@ open class CopyOrderTrackingService( private val cryptoUtils: CryptoUtils, private val marketService: MarketService, // 市场信息服务 private val telegramNotificationService: TelegramNotificationService? = null // 可选,避免循环依赖 -) { +) : ApplicationContextAware { private val logger = LoggerFactory.getLogger(CopyOrderTrackingService::class.java) // 协程作用域(用于异步发送通知) private val notificationScope = CoroutineScope(Dispatchers.IO + SupervisorJob()) + + private var applicationContext: ApplicationContext? = null + + override fun setApplicationContext(applicationContext: ApplicationContext) { + this.applicationContext = applicationContext + } + + /** + * 获取代理对象,用于解决 @Transactional 自调用问题 + */ + private fun getSelf(): CopyOrderTrackingService { + return applicationContext?.getBean(CopyOrderTrackingService::class.java) + ?: throw IllegalStateException("ApplicationContext not initialized") + } // 使用 Mutex 保证线程安全(按交易ID锁定) private val tradeMutexMap = ConcurrentHashMap() @@ -138,10 +154,11 @@ open class CopyOrderTrackingService( return@withLock Result.success(Unit) } - // 2. 处理交易逻辑 + // 2. 处理交易逻辑(通过代理对象调用,确保 @Transactional 生效) + val self = getSelf() val result = when (trade.side.uppercase()) { - "BUY" -> processBuyTrade(leaderId, trade, source) - "SELL" -> processSellTrade(leaderId, trade) + "BUY" -> self.processBuyTrade(leaderId, trade, source) + "SELL" -> self.processSellTrade(leaderId, trade) else -> { logger.warn("未知的交易方向: ${trade.side}") Result.failure(IllegalArgumentException("未知的交易方向: ${trade.side}"))