首页 > 解决方案 > Nodejs 续集读取器/写入器异步操作

问题描述

我正在为nodejs上的异步操作寻找解决方案-> sequelize (mysql)

我有一个接收消息的端点(一个 webhook),并执行以下操作:

[1]

sequelize.query(查找消息是否存在...)

[2]

如果 [1] 不存在,则 conversationsModel.create(....) 并返回 'X' 否则返回 'Y' (不创建对象)

我的经验是,我的读者/作家之间就像一场“竞赛”。

我发现一些参考资料说“事务”在这种情况下可能会有所帮助,但如果我们不在同一个请求上下文中(不同的传入 API 请求) - 无论如何它应该有帮助吗?

** 请注意,对于“读取”操作,我使用的是内联查询:

SELECT xxx FROM conversations where context="yyy" AND phoneNumber=:phoneNumber AND createdAt LIKE :time,`

对于“写”动作,我使用续集模型:

await conversationsModel.create({phoneNumber: to.phoneNumber,context: "team",displayName: "xxx",externalId,message,type: "media",});

你们能建议一个适当的解决方案吗?

提前致谢。

标签: mysqlnode.jssequelize.js

解决方案


这看起来像是何时使用.upsert静态方法的一个很好的例子sequelize(请参阅此处的文档)。这是 手册的链接。为了使用此方法,Conversation模型上必须有一个唯一键或主键。sequelize例如,假设contextphoneNumber属性有一个唯一索引。那么 upsert 声明会是这样的,

let [instance, created] = await ConversationsModel.upsert({
        phoneNumber: to.phoneNumber,
        context: "team",
        displayName: "xxx",
        externalId,
        message,
        type: "media",
    })

if (created) {
    // New conversation instance was created in database...
    //  Access the instance here...
} else {
    // New conversation instance was not created in database,
    //  but the existing instance was updated...
    //  Access the instance here...
}

重要提示: 正如上面链接中所指出的,当使用or时,值 forcreated仅设置为非空值,但由于正在使用原始问题状态,因此此解决方案就足够了。MySQLMSSQLMySQL

免责声明: 如果select语句和insert/update语句确实是在单独的 api 请求中完成的,那么如果不让两个请求以某种方式相互通信,就无法避免竞争条件。也许客户端程序可能有某种机制在单独的请求之间进行通信,以避免以某种方式通过数据库进行通信。


推荐阅读