【问题标题】:Can you manage transaction commit/rollback manually?您可以手动管理事务提交/回滚吗?
【发布时间】:2015-06-23 06:03:51
【问题描述】:

我想做这样的事情:

["START", "a", "b", "c", "STOP", "START", "d", "e", "STOP"].each do |message|
  if message == "START"
    Transaction.begin
  elsif message == "STOP"
    Transaction.commit if Transaction.active?
  else
    begin
      Message.create!(body: message)
    rescue
      Transaction.rollback
    end
  end
end

简而言之,我有一个“消息”流,我想对该流的部分进行事务处理。

只要流中出现“START”,就会开始新事务。每当出现“STOP”时,事务就被提交。

我正在为交易而苦苦挣扎。

我可以看到我可以执行 ActiveRecord::Base.transaction do ... end,但在这种情况下这将不起作用,除非我将所有内容都批量处理,这在此处是不可能的,因为流。

我看到 ActiveRecord 中隐藏了一个事务管理器,我可能会使用它 (https://github.com/rails/rails/blob/0d76ab9c6f01e6390ba8878a296ff9d3ac6b9aa8/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb),但我无法让我的测试通过它。

我认为问题的一部分也是 RSpec 的事务性装置干扰,尽管禁用这些似乎也不能解决问题。

任何帮助将不胜感激。

谢谢

【问题讨论】:

  • 你能提供更多数据吗?你在挣扎什么?也许显示失败的规格。

标签: mysql ruby-on-rails activerecord transactions


【解决方案1】:

您可以通过以下方式管理交易

manager = ActiveRecord::Base.connection.transaction_manager
...
manager.begin_transaction
...
manager.commit_transaction
...
manager.rollback_transaction

或者在你的情况下

manager = ActiveRecord::Base.connection.transaction_manager
["START", "a", "b", "c", "STOP", "START", "d", "e", "STOP"].each do |message|
  if message == "START"
    manager.begin_transaction
  elsif message == "STOP"
    manager.commit_transaction
  else
    begin
      Message.create!(body: message)
    rescue
      manager.rollback_transaction
    end
  end
end

【讨论】:

    【解决方案2】:

    我会这样做:

    messages.chunk {|value| value != 'START' && value != 'STOP'}.each do |is_data, bodies|
      if is_data
        Message.transaction do
          bodies.each {|body| Message.create(body: body)}
        end
      end
    end
    

    第一步是使用chunk 对消息进行分组。它的输出是一对数组。如果该对的第一个值为真,则第二个值为实体数组,如果不是,则实体只是真假。有了这样重组的数据,使用现有的事务方法就变得很简单了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-20
      相关资源
      最近更新 更多