fix: 修复 CopyOrderTrackingService 和 CopyTradingService 的 @Transactional 自调用问题
1. CopyOrderTrackingService 修复 - 实现 ApplicationContextAware 接口 - 添加 getSelf() 方法获取代理对象 - 在 processTrade() 中通过代理调用 processBuyTrade() 和 processSellTrade() - 确保两个子方法的 @Transactional 生效 2. CopyTradingService 修复 - 实现 ApplicationContextAware 接口 - 添加 getSelf() 方法获取代理对象 - 在 updateCopyTradingStatus() 中通过代理调用 updateCopyTrading() - 确保内部调用的 @Transactional 生效 修改的文件: - CopyOrderTrackingService.kt - CopyTradingService.kt
This commit is contained in:
+18
-2
@@ -14,6 +14,8 @@ import com.wrbug.polymarketbot.util.IllegalBigDecimal
|
|||||||
import com.wrbug.polymarketbot.util.JsonUtils
|
import com.wrbug.polymarketbot.util.JsonUtils
|
||||||
import com.wrbug.polymarketbot.util.toSafeBigDecimal
|
import com.wrbug.polymarketbot.util.toSafeBigDecimal
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.context.ApplicationContext
|
||||||
|
import org.springframework.context.ApplicationContextAware
|
||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
import org.springframework.transaction.annotation.Transactional
|
import org.springframework.transaction.annotation.Transactional
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
@@ -30,10 +32,24 @@ class CopyTradingService(
|
|||||||
private val monitorService: CopyTradingMonitorService,
|
private val monitorService: CopyTradingMonitorService,
|
||||||
private val jsonUtils: JsonUtils,
|
private val jsonUtils: JsonUtils,
|
||||||
private val gson: Gson
|
private val gson: Gson
|
||||||
) {
|
) : ApplicationContextAware {
|
||||||
|
|
||||||
private val logger = LoggerFactory.getLogger(CopyTradingService::class.java)
|
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
|
@Transactional
|
||||||
fun updateCopyTradingStatus(request: CopyTradingUpdateStatusRequest): Result<CopyTradingDto> {
|
fun updateCopyTradingStatus(request: CopyTradingUpdateStatusRequest): Result<CopyTradingDto> {
|
||||||
return updateCopyTrading(
|
return getSelf().updateCopyTrading(
|
||||||
CopyTradingUpdateRequest(
|
CopyTradingUpdateRequest(
|
||||||
copyTradingId = request.copyTradingId,
|
copyTradingId = request.copyTradingId,
|
||||||
enabled = request.enabled
|
enabled = request.enabled
|
||||||
|
|||||||
+21
-4
@@ -23,6 +23,8 @@ import com.wrbug.polymarketbot.service.common.MarketService
|
|||||||
import com.wrbug.polymarketbot.service.common.PolymarketClobService
|
import com.wrbug.polymarketbot.service.common.PolymarketClobService
|
||||||
import com.wrbug.polymarketbot.service.system.TelegramNotificationService
|
import com.wrbug.polymarketbot.service.system.TelegramNotificationService
|
||||||
import com.wrbug.polymarketbot.util.CryptoUtils
|
import com.wrbug.polymarketbot.util.CryptoUtils
|
||||||
|
import org.springframework.context.ApplicationContext
|
||||||
|
import org.springframework.context.ApplicationContextAware
|
||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
import org.springframework.transaction.annotation.Transactional
|
import org.springframework.transaction.annotation.Transactional
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
@@ -51,13 +53,27 @@ open class CopyOrderTrackingService(
|
|||||||
private val cryptoUtils: CryptoUtils,
|
private val cryptoUtils: CryptoUtils,
|
||||||
private val marketService: MarketService, // 市场信息服务
|
private val marketService: MarketService, // 市场信息服务
|
||||||
private val telegramNotificationService: TelegramNotificationService? = null // 可选,避免循环依赖
|
private val telegramNotificationService: TelegramNotificationService? = null // 可选,避免循环依赖
|
||||||
) {
|
) : ApplicationContextAware {
|
||||||
|
|
||||||
private val logger = LoggerFactory.getLogger(CopyOrderTrackingService::class.java)
|
private val logger = LoggerFactory.getLogger(CopyOrderTrackingService::class.java)
|
||||||
|
|
||||||
// 协程作用域(用于异步发送通知)
|
// 协程作用域(用于异步发送通知)
|
||||||
private val notificationScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
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锁定)
|
// 使用 Mutex 保证线程安全(按交易ID锁定)
|
||||||
private val tradeMutexMap = ConcurrentHashMap<String, Mutex>()
|
private val tradeMutexMap = ConcurrentHashMap<String, Mutex>()
|
||||||
|
|
||||||
@@ -138,10 +154,11 @@ open class CopyOrderTrackingService(
|
|||||||
return@withLock Result.success(Unit)
|
return@withLock Result.success(Unit)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 处理交易逻辑
|
// 2. 处理交易逻辑(通过代理对象调用,确保 @Transactional 生效)
|
||||||
|
val self = getSelf()
|
||||||
val result = when (trade.side.uppercase()) {
|
val result = when (trade.side.uppercase()) {
|
||||||
"BUY" -> processBuyTrade(leaderId, trade, source)
|
"BUY" -> self.processBuyTrade(leaderId, trade, source)
|
||||||
"SELL" -> processSellTrade(leaderId, trade)
|
"SELL" -> self.processSellTrade(leaderId, trade)
|
||||||
else -> {
|
else -> {
|
||||||
logger.warn("未知的交易方向: ${trade.side}")
|
logger.warn("未知的交易方向: ${trade.side}")
|
||||||
Result.failure(IllegalArgumentException("未知的交易方向: ${trade.side}"))
|
Result.failure(IllegalArgumentException("未知的交易方向: ${trade.side}"))
|
||||||
|
|||||||
Reference in New Issue
Block a user