如何避免使用DBIx :: Class :: ResultSet的find_or_create方法时的竞争条件? [英] How to avoid race conditions when using the find_or_create method of DBIx::Class::ResultSet?

查看:133
本文介绍了如何避免使用DBIx :: Class :: ResultSet的find_or_create方法时的竞争条件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

find_or_create


注意:因为find_or_create然后
可能基于结果插入,这种方法受到比赛
条件的限制。另一个进程可以在
之后的表中创建一个记录,find已经完成并且在创建开始之前。要避免
这个问题,请在事务中使用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.

推荐答案

不,文档不正确。单独使用事务可以避免此问题。它只保证在发生异常时回滚整个事务,以便不会有不一致的状态持续到数据库。

No, the documentation is incorrect. Using a transaction alone does not avoid this problem. It only guarantees that the whole transaction is rolled back if an exception should occur - so that no inconsistent state will be persisted to the database.

避免<强>这个问题你必须锁定表 - 内部的事务,因为所有的锁在事务结束时释放。像:

To avoid this problem you must lock the table - inside a transaction, because all locks are released at the end of a transaction. Something like:

BEGIN;
LOCK TABLE mytbl IN SHARE MODE;

-- do your find_or_create here

COMMIT;

但这不是一个魔法治疗一切。它可能会成为一个性能问题,并且可能存在死锁(并发事务相互尝试锁定另一个已经锁定的资源)。 PostgreSQL将检测到这样的条件并取消除了一个竞争事务之外的所有事务。您必须准备好在失败时重试操作。

But that's not a magic cure for everything. It can become a performance problem, and there may be deadlocks (concurrent transactions mutually trying to lock resources that the other one has locked already). PostgreSQL will detect such a condition and cancel all but one of the competing transactions. You must be prepared to retry the operation on failure.

关于锁的PostgreSQL手册。

如果你没有很多并发,你也可以忽略问题。时间段非常小,所以它只是很少实际发生。如果你抓到重复的键违规错误,这将没有任何伤害,那么你也覆盖了这一点。

If you don't have a lot of concurrency you might also just ignore the problem. The time slot is very tiny so it only very rarely actually happens. If you catch the duplicate key violation error, which will do no harm, then you have covered this, too.

这篇关于如何避免使用DBIx :: Class :: ResultSet的find_or_create方法时的竞争条件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆