簡體   English   中英

節點 MySQL 第二個查詢比第一個查詢執行得更快

[英]Node MySQL second query gets executed faster than first query

我有個問題。 在我的 NodeJS API 中。我使用Node-Binance-API package 來使用 Binance 的 API。 在這個 API 中,我可以使用 websocket 訂閱帳戶更改。訂閱我的帳戶的 function 如下所示:

exports.subscribeAccount = async (agentId) => {
    binance.websockets.userData((response) => {
        if (eventType === "outboundAccountPosition") {
            console.log("outboundAccountPosition")
        }
        else if (eventType === "executionReport") {
            const order = Order.executionReportToOrder(response, agentId);
            order.save();
        }
    })
}

order.save()方法如下所示:

save() {
    let sql = `
    INSERT INTO \`Order\` (
                orderId, agentId, symbol, clientOrderId, side, orderType, timeInForce, orderQuantity, orderPrice, stopPrice, icebergQuantity, originalClientOrderId, currentExecutionType, currentOrderStatus, orderRejectReason, lastExecutedQuantity, cumulativeFilledQuantity, lastExecutedPrice, commissionAmount, commissionAsset, transactionTime, tradeId, isOrderOnBook, isTradeMakerSide, creationTime, cumulativeQuoteAssetTransactedQuantity, lastQuoteAssetTransactedQuantity, quoteOrderQuantity
    ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
     ON DUPLICATE KEY UPDATE currentExecutionType=VALUES(currentExecutionType), currentOrderStatus=VALUES(currentOrderStatus), orderRejectReason=VALUES(orderRejectReason), lastExecutedQuantity=VALUES(lastExecutedQuantity), cumulativeFilledQuantity=VALUES(cumulativeFilledQuantity), lastExecutedPrice=VALUES(lastExecutedPrice), commissionAmount=VALUES(commissionAmount), commissionAsset=VALUES(commissionAsset), transactionTime=VALUES(transactionTime), tradeId=VALUES(tradeId), isOrderOnBook=VALUES(isOrderOnBook), isTradeMakerSide=VALUES(isTradeMakerSide), creationTime=VALUES(creationTime), cumulativeQuoteAssetTransactedQuantity=VALUES(cumulativeQuoteAssetTransactedQuantity), lastQuoteAssetTransactedQuantity=VALUES(lastQuoteAssetTransactedQuantity), quoteOrderQuantity=VALUES(quoteOrderQuantity);`;

    return db.execute(sql, [
        this.orderId,
        this.agentId,
        this.symbol,
        this.clientOrderId,
        this.side,
        this.orderType,
        this.timeInForce,
        this.orderQuantity,
        this.orderPrice,
        this.stopPrice,
        this.icebergQuantity,
        this.originalClientOrderId,
        this.currentExecutionType,
        this.currentOrderStatus,
        this.orderRejectReason,
        this.lastExecutedQuantity,
        this.cumulativeFilledQuantity,
        this.lastExecutedPrice,
        this.commissionAmount,
        this.commissionAsset,
        this.transactionTime,
        this.tradeId,
        this.isOrderOnBook,
        this.isTradeMakerSide,
        this.creationTime,
        this. cumulativeQuoteAssetTransactedQuantity,
        this.lastQuoteAssetTransactedQuantity,
        this.quoteOrderQuantity
    ]);
}

但是現在我遇到了以下問題。 websocket 工作得很好,它推送有關訂單的更新。 當我輸入立即執行的訂單時,此方法被調用兩次,緊接着調用一次。 第一個調用是NEW訂單,第二個調用是FILLED訂單。 order.save() function 使用mysql2 package 的db.execute() () function 將 object 寫入數據庫,但我可以看到有時第二個查詢比第一個查詢執行得更快,所以最后的 state 在我的數據庫是NEW的。 我怎樣才能防止這種情況發生? 當我看到第二個查詢進來時我可以取消第一個查詢或者讓它們依次執行嗎?

桌子

SHOW CREATE TABLE Order導致:

CREATE TABLE `Order` (
  `orderId` bigint(20) NOT NULL,
  `agentId` int(11) NOT NULL,
  `symbol` varchar(25) NOT NULL,
  `clientOrderId` varchar(255) NOT NULL,
  `side` enum('BUY','SELL') NOT NULL,
  `orderType` enum('MARKET','LIMIT','STOP_LOSS','STOP_LOSS_LIMIT','TAKE_PROFIT','TAKE_PROFIT_LIMIT') NOT NULL,
  `timeInForce` enum('GTC','IOC','FOK') NOT NULL,
  `orderQuantity` decimal(16,8) NOT NULL,
  `orderPrice` decimal(16,8) NOT NULL,
  `stopPrice` decimal(16,8) NOT NULL,
  `icebergQuantity` decimal(16,8) NOT NULL,
  `originalClientOrderId` varchar(255) NOT NULL,
  `currentExecutionType` enum('NEW','CANCELED','REPLACED','REJECTED','TRADE','EXPIRED') NOT NULL,
  `currentOrderStatus` enum('NEW','FILLED','CANCELED','EXPIRED','PENDING_CANCEL','PARTIALLY_FILLED') NOT NULL,
  `orderRejectReason` varchar(255) NOT NULL,
  `lastExecutedQuantity` decimal(16,8) NOT NULL,
  `cumulativeFilledQuantity` decimal(16,8) NOT NULL,
  `lastExecutedPrice` decimal(16,8) NOT NULL,
  `commissionAmount` decimal(16,8) NOT NULL,
  `commissionAsset` varchar(15) DEFAULT NULL,
  `transactionTime` bigint(20) NOT NULL,
  `tradeId` bigint(20) NOT NULL,
  `isOrderOnBook` tinyint(1) NOT NULL,
  `isTradeMakerSide` tinyint(1) NOT NULL,
  `creationTime` bigint(20) NOT NULL,
  `cumulativeQuoteAssetTransactedQuantity` decimal(16,8) NOT NULL,
  `lastQuoteAssetTransactedQuantity` decimal(16,8) NOT NULL,
  `quoteOrderQuantity` decimal(16,8) NOT NULL,
  PRIMARY KEY (`orderId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

如果這不是 binance 錯誤,則可以確定 websocket 回調事件按此處說明的正確順序出現。 作為第一步,您應該在回調 function 的開頭使用console.log()仔細檢查它。此外,我假設Order.executionReportToOrder是簡單的同步粘合代碼。

如果這一切都是真的,超車一定會出現在隨后的異步處理中。 然后你可以嘗試使用像async-mutex這樣的 mutex-lib 來保留回調執行的順序,如下所示:

exports.subscribeAccount = async (agentId) => {
    binance.websockets.userData((response) => {
        console.log("Add some meaningful debug information here!")
        mutex.runExclusive(() => {
            console.log("Add some meaningful debug information here!")
            if (eventType === "outboundAccountPosition") {
                console.log("outboundAccountPosition")
            }
            else if (eventType === "executionReport") {
              const order = Order.executionReportToOrder(response, agentId);
              order.save();
            }
        })
    })
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM