多个pods/micro-servicesupdate/insert同一条记录

Multiple pods/micro-services update/insert the same record

我有多个服务都收到请求 示例请求有 3 个字段 - 货币、日期、金额

现有 table 有 2 个条目

关键字、货币、日期、金额

123,美元,8 月 1 日,100

234,欧元,12 月 1 日,50

插入大小写

如果 table 中不存在包含接收到的货币、日期组合的条目,则会插入一个新条目。 例如对于以上 table,如果我们收到 (USD, 2 Aug, 20),将插入新条目

更新案例

如果在 table 中已经存在一个条目与收到的货币,日期组合现有条目通过更新金额字段来更新 例如对于以上 table,如果我们收到 (USD, 1 Aug, 30),现有条目将更新 123,更新后的金额将为 100+30 = 130

场景问题

kubernetes/similar 平台中有 3 个服务 运行 实例,以下三个服务大约同时接收请求 第一项服务收到请求(美元,9 月 1 日,100) 第二项服务收到请求(美元,9 月 1 日,200) 第三项服务收到请求(美元,9 月 1 日,300)

理想情况应该是,无论哪个服务先处理,都将创建第一个插入条目,其余两个服务将更新该条目的金额

期望的最终结果:

美元,9 月 1 日,600

但是,观察到的结果之一是,2 个服务最终插入了记录,并且根据应用层处理,第 3 个条目可能会失败,因为它找不到唯一的条目来更新金额,或者它最终更新了数据库中返回的条目之一

美元,9 月 1 日,100

美元,9 月 1 日,500

奎斯顿

应该如何以及在何处处理?在数据库中使用锁还是在Java应用层?

这似乎是一个并发问题,我想你正在做两个查询来做到这一点。首先,您尝试在数据库中查找记录,其次,根据它是否存在进行更新或插入。 但是,如果两个请求同时(或几乎同时)到达,则两者进行第一个查询,并且由于该货币不存在,因此它们进行插入。

为了解决这个问题,我将按照Kayaman的建议在货币中添加一个唯一约束,并将查询更改为upsert(它是某些数据库支持的更新和插入查询的组合)以进行查询原子所以如果插入失败因为已经有一个具有相同货币的记录它会做一个更新

这是关于如何在 Postgresql 中执行更新插入的文档 https://www.postgresqltutorial.com/postgresql-upsert/