繁体   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