仕事で最近rais4を使って開発してるんだけど、トランサクションについてわからんのでちょっと調べてみた。
必要な仕様としては、インサートする配列があって、どこかでインサートがこけたらrollbackして成功していたインサートもなかったことにする。
自分これ系の仕様嫌いなんだけど。。。
しょうがないからやってみた。
まず、バルクインサートさせるために「activerecord-import」を使う。
Gemfileに下記を記述して
gem 'activerecord-import'
bundle update
で、mysqlでテーブル3つ用意。
foodsテーブル
order integer not null
name string
jobsテーブル
order integer not null
name string
likeテーブル
order integer not null
name string
どれも構成はおんなじ。
ネーミングセンスはテストなので気にしないでちょ(汗)
データはあらかじめ入れておくよ。
簡潔にテストしたいのでスタティックなコントローラに下記を記述。
orderはnot nullなのでorderのところに「nil」を入れておいて、わざとエラーにさせる。
コントローラに書くコードは下記のコード。
p '------------------------'
ng=[
{ :order => 10, :name => 'ああああ'},
{ :order => 11, :name => 'えええ'},
{ :order => nil, :name => 'いいい'},
{ :order => 13, :name => 'ううう'},
{ :order => 14, :name => 'おおお'},
]
ok=[
{ :order => 10, :name => 'ああああ'},
{ :order => 11, :name => 'えええ'},
{ :order => 12, :name => 'いいい'},
{ :order => 13, :name => 'ううう'},
{ :order => 14, :name => 'おおお'},
]
j = []
ng.each do |i|
j << Job.new(i)
end
f = []
ok.each do |i|
f << Food.new(i)
end
begin
Job.transaction do
Food.import f
Job.import j
a = Like.where(Like.arel_table[:order].lteq(10))
a.update_all({:name => 'きゃー'})
end
rescue ex
p '----------- error -------'
p ex.messages
end
どっかの記事でRails(4)は複数のトランザクションをサポートしない。。。
みたいな記事を見たんだけど、構わず無作為にピックアップしたモデルを使ってトランザクションしてみる。
実行してみた結果、クエリがこけたときは見事rollbackされることが確認できた。
どのテーブルも更新されませんでした。
念のため、Food, Job, Likeでそれぞれこけさせてみたが、結果は同じ更新されてませんでした。
もちろん、成功時は三つのテーブルに更新がかかっているのも確認ができた。
モデル.transaction doで複数のモデルの更新管理ができることはわかったけど、Rails自身がバージョンアップしたら動かなくなる可能性もあるので注意かも?
0 件のコメント:
コメントを投稿