加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby-on-rails – 如何在Rails中启动事务的情况下运行迁移?

发布时间:2020-12-16 19:59:10 所属栏目:百科 来源:网络整理
导读:我从 OpenCongress运行一些奇怪的Postgres迁移代码,我收到这个错误: RuntimeError: ERROR C25001 MVACUUM cannot run inside a transaction blockFxact.c L2649 RPreventTransactionChain: VACUUM FULL ANALYZE; 所以我想尝试运行它,而不会被交易包裹. 解决
我从 OpenCongress运行一些奇怪的Postgres迁移代码,我收到这个错误:
RuntimeError: ERROR     C25001  MVACUUM cannot run inside a transaction block
Fxact.c  L2649   RPreventTransactionChain: VACUUM FULL ANALYZE;

所以我想尝试运行它,而不会被交易包裹.

解决方法

ActiveRecord :: Migration有以下私有方法,在运行迁移时被调用:
def ddl_transaction(&block)
  if Base.connection.supports_ddl_transactions?
    Base.transaction { block.call }
  else
    block.call
  end
end

正如你可以看到的,如果连接支持它,它会将迁移包装在一个事务中.

在ActiveRecord :: ConnectionAdapters :: PostgreSQLAdapter你有:

def supports_ddl_transactions?
  true
end

SQLite 2.0及更高版本也支持迁移事务.
在ActiveRecord :: ConnectionAdapters :: SQLiteAdapter你有:

def supports_ddl_transactions?
  sqlite_version >= '2.0.0'
end

那么,为了跳过交易,你需??要以某种方式规避这一点.
这样的事情可能会起作用,虽然我还没有测试过:

class ActiveRecord::Migration
  class << self
    def no_transaction
      @no_transaction = true
    end

    def no_transaction?
      @no_transaction == true
    end
  end

  private

    def ddl_transaction(&block)
      if Base.connection.supports_ddl_transactions? && !self.class.no_transaction?
        Base.transaction { block.call }
      else
        block.call
      end
    end
end

然后,您可以按如下方式设置迁移:

class SomeMigration < ActiveRecord::Migration
  no_transaction

  def self.up
    # Do something
  end

  def self.down
    # Do something
  end
end

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读