1

Railsのドキュメントによると、複数のデータベースを含むネストされたトランザクションは機能するはずです:

User.transaction do
  User.create(:username => 'Kotori')
  User.transaction(:requires_new => true) do
    User.create(:username => 'Nemu')
    raise ActiveRecord::Rollback
  end
end

親トランザクションもロールバックするように、ネストされたトランザクションでロールバックを伝播するにはどうすればよいでしょうか?

ありがとう

4

2 に答える 2

1

まず、コードが複数のデータベースを使用していません。どちらも Client モデルからの接続を使用します。

次に、DBMS を指定しません。異なる DB ドライバーには異なるプロパティがあり、すべてがネストされたトランザクションを実装しているわけではありません。どのDBを使用していますか?

私はまさにあなたがやりたいことをやっただけで、2 つの postgres DB を使用しています。ActiveRecord::Rollback をスローするだけで、囲んでいるトランザクションは終了しますが、それ以上の例外はスローされません。ネストされたトランザクションが失敗した場合、外側のトランザクションがロールバックされることを確認したい。したがって、内部トランザクションで例外をキャッチし、そこからロールバックを発生させます。

注: アカウント モデルとユーザー モデルは異なるデータベースを使用しますが、どちらも Postgres の同じインスタンスで実行されます。また、begin rescue 句を省略した場合、コードは両方のデータベースをロールバックしますが、外側のトランザクションが終了した後にスタックを巻き戻す例外が残ります。最後に、外部トランザクションのコミットに問題がある場合、内部トランザクションはロールバックされないと思います。私の場合、それは問題ではありません。ネストされたトランザクションで DB1 コードをラップし、DB2 トランザクションを開始する前にコミットすることができます。

Account.transaction do
  begin
    acc = Account.do_something_to_accounts
    User.transaction do
      User.do_something_to_users
    end
  rescue => e
    raise ActiveRecord::Rollback
  end
end
于 2012-12-18T18:16:45.187 に答える