在 Postgresql 事务中创建唯一索引

Create on unique index within transactions in Postgresql

我有一个名为 Account 的 table,其中有一列 name。列上有一个唯一索引。我有一笔交易:

begin
create an account with name("ABC")
publish an event to Kafka
end

不知道会不会出现这种情况:

Request 1: .....transaction start.......create account name("ABC").......publish Kafka event.......commit transaction
Request 2: ..........transaction start.........create account name("ABC").......publish Kafka event.......commit transaction

两个请求同时发生。因为这个事务不会看到另一个事务中的数据变化,一个提交时会失败,一个会成功。我会收到 2 个 Kafka 事件吗?

您将不会收到第二个 Kafka 事件。

由于 name 属性上的唯一索引,第二笔交易被迫等待第一笔交易完成,然后才能完成插入与 PostgreSQL documentation 中描述的同名帐户:

If a conflicting row has been inserted by an as-yet-uncommitted transaction, the would-be inserter must wait to see if that transaction commits. If it rolls back then there is no conflict. If it commits without deleting the conflicting row again, there is a uniqueness violation. (In practice we just wait for the other transaction to end and then redo the visibility check in toto.)

在第一个事务提交后,第二个事务继续插入并引发 unique_violation 异常,如:

SQL Error [23505]: ERROR: duplicate key value violates unique constraint "idx_name" Detail: Key (name)=(ABC) already exists.

情况会导致这样的结果:

Request 1: .....transaction start.......create account name("ABC").......publish Kafka event.......commit transaction
Request 2: ..........transaction start.......create account name("ABC")-----------------------------Error(unique_violation)

(我添加了 --- 以指示阻止 create account name("ABC") 命令)。