控制流

时间:2016-07-06 22:24:42

标签: sql postgresql orm locking distributed

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

我可以想到两个选择:

A)使用分布式锁定来确保操作跨进程/系统是原子操作。检查记录是否存在。相应地获取或创建记录。

B)始终尝试插入记录。允许数据库引发唯一约束违规错误并捕获应用程序中的异常。如果引发异常,那么它就存在,所以请改为记录。

选项A显然更正确,但性能更高?

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

你能否给我一个具体的理由将选项B与具体证据一起使用?

谢谢!

1 个答案:

答案 0 :(得分:1)

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

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

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