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

前端之家收集整理的这篇文章主要介绍了ruby-on-rails – 如何在Rails中启动事务的情况下运行迁移?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我从 OpenCongress运行一些奇怪的Postgres迁移代码,我收到这个错误
  1. RuntimeError: ERROR C25001 MVACUUM cannot run inside a transaction block
  2. Fxact.c L2649 RPreventTransactionChain: VACUUM FULL ANALYZE;

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

解决方法

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

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

在ActiveRecord :: ConnectionAdapters :: PostgresqlAdapter你有:

  1. def supports_ddl_transactions?
  2. true
  3. end

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

  1. def supports_ddl_transactions?
  2. sqlite_version >= '2.0.0'
  3. end

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

  1. class ActiveRecord::Migration
  2. class << self
  3. def no_transaction
  4. @no_transaction = true
  5. end
  6.  
  7. def no_transaction?
  8. @no_transaction == true
  9. end
  10. end
  11.  
  12. private
  13.  
  14. def ddl_transaction(&block)
  15. if Base.connection.supports_ddl_transactions? && !self.class.no_transaction?
  16. Base.transaction { block.call }
  17. else
  18. block.call
  19. end
  20. end
  21. end

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

  1. class SomeMigration < ActiveRecord::Migration
  2. no_transaction
  3.  
  4. def self.up
  5. # Do something
  6. end
  7.  
  8. def self.down
  9. # Do something
  10. end
  11. end

猜你在找的Ruby相关文章