[Rails] Active Record Transactions の requires_new
transactionをネストしたときに、子のtransaction内でActiveRecord::Rollback
を投げてもロールバックされない。
irb(main):059:0> User.transaction do irb(main):060:1* User.create(username: 'Kotori') irb(main):061:1> User.transaction do irb(main):062:2* User.create(username: 'Nemu') irb(main):063:2> raise ActiveRecord::Rollback irb(main):064:2> end irb(main):065:1> end (0.1ms) begin transaction User Create (0.7ms) INSERT INTO "users" ("username", "created_at", "updated_at") VALUES (?, ?, ?) [["username", "Kotori"], ["created_at", "2019-07-18 14:31:50.104487"], ["updated_at", "2019-07-18 14:31:50.104487"]] User Create (0.1ms) INSERT INTO "users" ("username", "created_at", "updated_at") VALUES (?, ?, ?) [["username", "Nemu"], ["created_at", "2019-07-18 14:31:50.106418"], ["updated_at", "2019-07-18 14:31:50.106418"]] (1.7ms) commit transaction => nil irb(main):066:0> User.all.pluck(:username) (0.1ms) SELECT "users"."username" FROM "users" => ["Kotori", "Nemu"]
requires_new: true
とすると子のtransaction内だけロールバックする。
irb(main):073:0> User.transaction do irb(main):074:1* User.create(username: 'Kotori') irb(main):075:1> User.transaction(requires_new: true) do irb(main):076:2* User.create(username: 'Nemu') irb(main):077:2> raise ActiveRecord::Rollback irb(main):078:2> end irb(main):079:1> end (0.1ms) begin transaction User Create (0.3ms) INSERT INTO "users" ("username", "created_at", "updated_at") VALUES (?, ?, ?) [["username", "Kotori"], ["created_at", "2019-07-18 14:33:44.891135"], ["updated_at", "2019-07-18 14:33:44.891135"]] (0.0ms) SAVEPOINT active_record_1 User Create (0.1ms) INSERT INTO "users" ("username", "created_at", "updated_at") VALUES (?, ?, ?) [["username", "Nemu"], ["created_at", "2019-07-18 14:33:44.892205"], ["updated_at", "2019-07-18 14:33:44.892205"]] (0.0ms) ROLLBACK TO SAVEPOINT active_record_1 (1.5ms) commit transaction => nil irb(main):080:0> User.all.pluck(:username) (0.1ms) SELECT "users"."username" FROM "users" => ["Kotori"]
ちなみに、普通に例外を投げると親のtransactionもロールバックする。普通。
irb(main):087:0> User.transaction do irb(main):088:1* User.create(username: 'Kotori') irb(main):089:1> User.transaction do irb(main):090:2* User.create(username: 'Nemu') irb(main):091:2> raise irb(main):092:2> end irb(main):093:1> end (0.1ms) begin transaction User Create (0.8ms) INSERT INTO "users" ("username", "created_at", "updated_at") VALUES (?, ?, ?) [["username", "Kotori"], ["created_at", "2019-07-18 14:36:22.828138"], ["updated_at", "2019-07-18 14:36:22.828138"]] User Create (0.2ms) INSERT INTO "users" ("username", "created_at", "updated_at") VALUES (?, ?, ?) [["username", "Nemu"], ["created_at", "2019-07-18 14:36:22.830153"], ["updated_at", "2019-07-18 14:36:22.830153"]] (1.4ms) rollback transaction Traceback (most recent call last): 3: from (irb):87 2: from (irb):89:in `block in irb_binding' 1: from (irb):91:in `block (2 levels) in irb_binding' RuntimeError () irb(main):094:0> User.all.pluck(:username) (0.1ms) SELECT "users"."username" FROM "users" => []