How do I query the database after a Postgres exception?
在插入Postgres数据库时,我在处理并发问题时遇到了一些麻烦。 该模型在索引列上具有唯一性约束,Postgres表也是如此。 有时两个线程会同时尝试插入相同的记录(这是不可避免的),在这种情况下,两个都通过了模型验证,但第二个线程违反了Postgres验证。 所以我抓住了异常,一切都很好。 这不是问题。
问题是我的方法需要从数据库返回对象,所以我查询db以获取第一个线程插入的记录(我可以放心地假设它与第二个线程中的那个相同)。 但是,由于插入失败,事务仍处于无效状态,因此失败。
我的问题是:如何避免在rescue块中抛出的第二个异常,和/或启用该方法返回第一个线程插入的记录?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | class Place validates :index_column, uniqueness: TRUE, allow_nil: TRUE def SELF.create_and_insert(some_params) more_params = additional_params(some_params) place = Place.new(some_params, more_params) BEGIN place.save # INSERT INTO place TABLE. This initiates a TRANSACTION. rescue ActiveRecord::RecordNotUnique => e # Oops! Another thread beat us TO it. # The TRANSACTION IS now IN an invalid state. place = Place.find_by(index_column: some_params.id) # This throws a NEW exception END place END END |
在PostgreSQL中,您在事务中设置一个保存点,以便您可以回滚导致该错误的事务部分; 这称为子交易。
您可以在Ruby on Rails中使用它,请参阅文档。