質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

1回答

697閲覧

transaction処理の方法について

ryochinBasket

総合スコア2

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

0クリップ

投稿2021/12/03 03:17

前提・実現したいこと

bicycle tableのnumberを変更したときに、history tableのbicycle_idを更新処理を書いています。

1 bicycle tableのnumberがすでに存在する場合
numberに該当するidを、bicycle_idとしてhistory tableを更新。

2 bicycle tableのnumberが存在しない場合
bicycle tableに新たに登録、作成されたidを、history tableの該当レコードを更新。

ここで、
2番のbicycle tableに登録後、history tableの更新時にエラーがあった場合、
bicycle tableに登録されたものは、rollbackされるようにするためにどうすればよいでしょうか?

transaction処理を書いているんですが、うまく処理されませんでした。

該当のソースコード

controller

1 def correction 2 logger.info "update start" 3 record = History.find(params[:id]) 4 bicycle = Bicycle.find_by(number: params[:number]) 5 6 # ------- transaction start ------------- 7 ActiveRecord::Base.transaction do 8 9 # number あり 10 if bicycle 11 begin 12 record.update!(bicycle_id: vehicle.id, correction_flg: 1) 13 render json: { status: 200, message: "Success correction" } 14 rescue 15 render status: :internal_server_error 16 end 17 else 18 # number なし 19 logger.info "no result. insert new record." 20 begin 21 bicycle = Bicycle.create!(number: params[:number]) 22 if bicycle 23 record.update!(bicycle_id: bicycle.id, correction_flg: 1) 24 render json: { status: 200, message: "Success correction" } 25 end 26 rescue 27 render status: :internal_server_error 28 end 29 end #if bicycle end 30 end # transaction end 31end # correction

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2021/12/03 03:59

> うまく処理されませんでした。 具体的に、どうなっているのでしょうか。
guest

回答1

0

ベストアンサー

前提としてActiveRecordではtransaction do ~ endの中で例外が起きた時にロールバックが行われます。
したがって、その中でbegin, rescueで例外を握りつぶしてしまったら、
ロールバックのトリガーが発動しません。

ざっくり言うとこういう事です。
begin~endはトランザクションの外に持っていきます。

ruby

1begin 2 ActiveRecord::Base.transaction do 3 `ロールバックするためにはここで例外を出さなければならないので、 4 ここにはbegin-rescue-endは書いてはいけない` 5 end 6 7 # 成功(コミット) 8 render json: { status: 200, message: "Success correction" } 9rescue Exception => e 10 # 失敗(ロールバック) 11 render status: :internal_server_error 12end

投稿2021/12/03 04:33

mingos

総合スコア4032

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問