gpt4 book ai didi

perl - 使用 DBIx::Class::ResultSet 的 find_or_create 方法时如何避免竞争条件?

转载 作者:太空狗 更新时间:2023-10-30 01:51:24 25 4
gpt4 key购买 nike

来自 find_or_create 的文档:

Note: Because find_or_create() reads from the database and then possibly inserts based on the result, this method is subject to a race condition. Another process could create a record in the table after the find has completed and before the create has started. To avoid this problem, use find_or_create() inside a transaction.

在 PostgreSQL 的事务中仅使用 find_or_create() 就足够了吗?

最佳答案

不,文档不正确。单独使用事务不能避免这个问题。它只保证在发生异常时回滚整个事务 - 这样就不会将不一致的状态持久保存到数据库中。

避免这个问题,您必须在事务中锁定表,因为所有锁都在事务结束时释放。像这样的东西:

BEGIN;
LOCK TABLE mytbl IN SHARE MODE;

-- do your find_or_create here

COMMIT;

但这并不是包治百病的 Elixir 。它可能会成为性能问题,并且可能会出现死锁(并发事务相互尝试锁定另一个已经锁定的资源)。 PostgreSQL 将检测到这种情况并取消除一个竞争事务之外的所有事务。您必须准备好在失败时重试该操作。

The PostgreSQL manual about locks.

如果你没有很多并发,你也可以忽略这个问题。时间段非常小,因此实际上很少发生。如果您捕获了重复 key 违规错误,这不会造成任何伤害,那么您也已经涵盖了这一点。

关于perl - 使用 DBIx::Class::ResultSet 的 find_or_create 方法时如何避免竞争条件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10264030/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com