Postgres异常后如何查询数据库?

时间:2017-01-31 19:08:21

标签: ruby-on-rails postgresql ruby-on-rails-3

插入Postgres数据库时,我遇到了处理并发问题的麻烦。该模型在索引列上具有唯一性约束,Postgres表也是如此。有时两个线程会同时尝试插入相同的记录(这是不可避免的),在这种情况下,两个都通过了模型验证,但第二个线程违反了Postgres验证。所以我抓住了异常,一切都很好。这不是问题。

问题是我的方法需要从数据库返回对象,所以我查询db以获取第一个线程插入的记录(我可以放心地假设它与第二个线程中的那个相同)。但是,由于插入失败,事务仍然处于无效状态,因此失败。

我的问题是:如何避免在rescue块中抛出的第二个异常,和/或启用该方法返回第一个线程插入的记录?

  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

1 个答案:

答案 0 :(得分:1)

在PostgreSQL中,您在事务中设置了savepoint,以便您可以回滚导致错误的事务部分;这称为子交易

您可以在Ruby on Rails中使用它,请参阅the documentation