控制流的分布式锁定与约束违反异常处理

Distributed locking vs constraint violation exception handling for control flow

我有一个分布式系统需要执行原子数据库操作。本质上,应用程序需要执行 find or create.

我能想到两个方案:

A) 使用分布式锁确保操作在 processes/systems 中是原子的。检查记录是否存在。相应地获取或创建记录。

B) 始终尝试插入记录。允许数据库引发唯一约束冲突错误并捕获应用程序中的异常。如果引发异常,则异常存在,因此改为获取记录。

选项 A 显然更正确 但哪个更高效?

控制流使用异常处理很臭,但真的有那么可怕吗?我觉得选项 B 更具可读性,也更容易推理。另外,它不需要锁定数据库。

谁能给我一个具体的理由使用选项 B 和具体证据?

谢谢!

锁显然是有代价的;即使您的进程在尝试获取它们时没有阻塞,它们仍然需要时间和资源来管理。

据我所知,引发异常不会产生任何后果,前提是它不会触发一些先前插入的数据的回滚(膨胀您的表并为 autovacuum 创建工作)。

但是从 Postgres 9.5 开始,您可以使用 INSERT ... ON CONFLICT DO NOTHING 语句来做同样的事情——没有异味。您的客户端库应该 return 受影响的行数,这将告诉您 INSERT 是否成功。