关于 INSERT 并发到具有复合主键的表的最佳实践?

Pie*_*che 5 postgresql concurrency locking relational-theory

说我有表usersteamsteams_users结表(team_IDuser_ID/复合PK)。如果我想将用户添加到团队中,那么在性能/并发问题方面,最佳选择是什么?

选项1)

首先查询表并查看关系是否已经存在,如果它只是通知发出请求的用户。

选项 2)

插入时,使用WHERE EXISTS语法(第二个示例)。

选项 3)

将 Postgres 9.5 Beta 用于 UPSERT 功能。(我想在学校项目中使用 Beta 版本不是一个坏主意吗?)。

在并发方面,哪种选择最好。我对 SQL 不是很有经验(只是 CRUD 应用程序的标准内容)。但据我所知,在第一个选项中,另一个用户可以在查询联结表之后但在自己实际插入关系之前插入关系。我想不会有任何重复项,因为我在该联结表中有一个复合主键,但我觉得让它成为例外并继续是不好的做法。此外,在我当前的代码中,在这种情况下我会返回 500 http 状态(因为 db 异常),这似乎并不正确。

我读过我可以通过“锁定”数据库/表来部分解决上述问题,但我不知道这是否是正确的方法。

最后,我不知道第二个选项是否存在竞争条件。

Joi*_*dio 1

如果您担心数据完整性(确保在有人有机会读取数据之前填充所有适当的表),那么您需要确保所有三个插入都在同一个事务块内完成。

Begin transaction
Insert 1) insert into users
Insert 2) insert into teams
Insert 3) insert into teams_users
Commit transaction
Run Code Online (Sandbox Code Playgroud)

如果您不在同一事务块中执行这些操作,则有人可能会在插入 team 和 team_users 之前从用户中进行选择。