まず、コードが複数のデータベースを使用していません。どちらも 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