【问题标题】:How do I query the database after a Postgres exception?Postgres 异常后如何查询数据库?
【发布时间】:2017-06-17 08:41:26
【问题描述】:

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

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

我的问题是:如何避免在救援块中引发第二个异常,和/或使该方法能够返回第一个线程插入的记录?

  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

【问题讨论】:

  • 您的第二个例外究竟是什么?
  • @archana ActiveRecord::StatementInvalid: PG::InFailedSqlTransaction: 错误:当前事务被中止,命令被忽略直到事务块结束:选择“地方”。*从“地方”到“地方”。 "id" = 'some_id' LIMIT 1
  • @archana 所以基本上,交易还没有结束。我没有开始交易,但save 做了。实现after_rollback 无济于事,因为我需要从create_and_insert 返回一个值。我可以从create_and_insert 内回滚吗?
  • 这里是解决方案,只需快速谷歌搜索:stackoverflow.com/questions/21138207/…
  • @archana 谢谢。您的 Google 技能堪称典范。

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


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 2019-03-08
    • 1970-01-01
    • 2019-04-25
    • 2011-04-17
    相关资源
    最近更新 更多