【发布时间】:2019-09-09 10:44:02
【问题描述】:
我有一个 Lambda,它可以一次接收数千个事件。默认情况下保留并发,这意味着 AWS 将启动多个实例来处理传入事件。 Lambda 获取数据并将一些数据插入到数据库中(如果该数据尚不存在)。 Lambda 是用 Node.js 编写的,并使用 Knex 连接到 Postgres 数据库。
Lambda 本质上包含这个逻辑:
Does a record with ID X exist?
a. Yes: do nothing
b. No: create a new record with ID X.
问题在于,当 50 个 Lambda 同时启动时,它们会进入竞争条件,例如,其中 3 或 4 个将同时检查现有记录(或彼此相隔几微秒) ) 并没有找到它,因此插入了多个重复的记录。
我知道解决这个问题的一种方法是在表上创建一个唯一约束,以防止多个 ID 为 X 的记录。那么我的逻辑将如下所示:
Does a record with ID X exist?
a. Yes: do nothing
b. No: create a new record with ID X.
b.1. Did that succeed?
a. Yes: continue on.
b. No, it threw a unique constraint error: go back to line 1.
这似乎有点做作,但应该可以。有更好的选择吗?
编辑:
这是实际代码:
let location = await Location.query().where({ external_id }).first();
if(!location){
location = await Location.query().insert({
name,
external_id
});
}
【问题讨论】:
-
我认为这个问题不一定特定于 aws-lambda 或 postgresql ......它被概括为 consistency models 以及采取哪条路线。 Jespen 有一些图表可以帮助解释每个模型的优势
-
也许一个很好的初读会是:Correctness。这个链接有更多的图来帮助解释。
-
@JaromandaX 我已经添加了 actual 代码。它确实符合我的解释,但我希望你满意。
-
某些数据库允许您执行“更新插入”操作,这意味着:“更新如果找到,否则在插入”
-
@RichS 这是一个有趣的想法。我认为 Postgres 确实支持这一点,但不确定 Knex 是否支持。我会调查的。谢谢你的想法。
标签: javascript node.js postgresql aws-lambda knex.js