10766


clockworkを使って定期処理を実装したのですが、トランザクションロールバックしてしまいます。どうすれば直るでしょうか？なんのトランザクションがロールバックしているのでしょうか？ちなみにローカル環境下では定期処理自体は動いています。

**ログ**

[code]

     (0.1ms)  begin transaction
       (0.1ms)  rollback transaction
       (0.3ms)  SELECT COUNT(*) FROM "items" WHERE "items"."deleted_at" IS NULL AND ("items"."limit_day" BETWEEN '2013-12-24 00:00:00.000000' AND '2015-05-28 17:10:36.818442') AND "items"."trade" = 't' AND "items"."limit_check" = 'f'
       (0.1ms)  begin transaction
       (0.1ms)  rollback transaction
       (0.3ms)  SELECT COUNT(*) FROM "items" WHERE "items"."deleted_at" IS NULL AND ("items"."limit_day" BETWEEN '2013-12-24 00:00:00.000000' AND '2015-05-28 17:11:36.916917') AND "items"."trade" = 't' AND "items"."limit_check" = 'f'
       (0.2ms)  begin transaction
       (0.1ms)  rollback transaction
       (0.2ms)  SELECT COUNT(*) FROM "items" WHERE "items"."deleted_at" IS NULL AND ("items"."limit_day" BETWEEN '2013-12-24 00:00:00.000000' AND '2015-05-28 17:12:36.602979') AND "items"."trade" = 't' AND "items"."limit_check" = 'f'
       (0.1ms)  begin transaction
       (0.2ms)  rollback transaction
       (0.3ms)  SELECT COUNT(*) FROM "items" WHERE "items"."deleted_at" IS NULL AND ("items"."limit_day" BETWEEN '2013-12-24 00:00:00.000000' AND '2015-05-28 17:13:36.908669') AND "items"."trade" = 't' AND "items"."limit_check" = 'f'
       (0.1ms)  begin transaction
       (0.1ms)  rollback transaction
       (0.4ms)  SELECT COUNT(*) FROM "items" WHERE "items"."deleted_at" IS NULL AND ("items"."limit_day" BETWEEN '2013-12-24 00:00:00.000000' AND '2015-05-28 17:13:44.742769') AND "items"."trade" = 'f' AND "items"."limit_check" = 'f'
       (0.1ms)  begin transaction
       (0.1ms)  rollback transaction
       (0.2ms)  SELECT COUNT(*) FROM "items" WHERE "items"."deleted_at" IS NULL AND ("items"."limit_day" BETWEEN '2013-12-24 00:00:00.000000' AND '2015-05-28 17:14:36.719051') AND "items"."trade" = 't' AND "items"."limit_check" = 'f'
       (0.2ms)  begin transaction
       (0.1ms)  rollback transaction
       (0.2ms)  SELECT COUNT(*) FROM "items" WHERE "items"."deleted_at" IS NULL AND ("items"."limit_day" BETWEEN '2013-12-24 00:00:00.000000' AND '2015-05-28 17:15:36.733665') AND "items"."trade" = 't' AND "items"."limit_check" = 'f'
       (0.3ms)  begin transaction
       (0.1ms)  rollback transaction
       (0.3ms)  SELECT COUNT(*) FROM "items" WHERE "items"."deleted_at" IS NULL AND ("items"."limit_day" BETWEEN '2013-12-24 00:00:00.000000' AND '2015-05-28 17:16:36.400022') AND "items"."trade" = 't' AND "items"."limit_check" = 'f'
    
[/code]

**lib/tasks/item.rake**

[code]

    namespace :item do
      desc "TODO"
      #アイテムのリミットとトレードチェック取引ナビ作成
      task trade_limit_end_item_check: :environment do
    
    
        no_check_item = Item.where(limit_day: Time.mktime(2014, 12, 24, 00, 00, 00).prev_year..Time.now, trade: true, limit_check: false)
    
    
        if no_check_item.count > 0
          Item.transaction do
            no_check_item.find_each do |item|
    
              #該当ユーザ
              warrant = Warrant.find_by(item_id: item.id)
    
    
              #取引ナビ生成
              navi = Navi.create(exhibitor_id: item.user_id, proprietor_id: warrant.holder_id, item_id: item.id, status: false, score_judge: true, score_body:'')
    
              #お知らせ一覧 取引ナビお知らせ
              Todo.create(exhibitor_id: item.user_id, proprietor_id: warrant.holder_id, item_id: item.id, navi_id: navi.id, body_num: 90000, status: false)
    
              #ループ中のcreateのパフォーマンスも気になるようであれば、activerecord-importというgemを利用する
    
              #アイテムタイムリミットチェックフラグ
              item.update({limit_check: true, phase: 20000})
            end
          end
        end
      end
    
    
    
    
    
      #アイテムタイムリミッチェック
      task limit_day_check: :environment do
    
    
        limit_day_end_item = Item.where(limit_day: Time.mktime(2014, 12, 24, 00, 00, 00).prev_year..Time.now, trade: false, limit_check: false)
    
    
        if limit_day_end_item.count > 0
          Item.transaction do
            limit_day_end_item.find_each do |item|
    
    
              #アイテムタイムリミットチェックフラグ
              item.update({limit_check: true, phase: 10010})
    
            end
          end
        end
      end
    end
    
[/code]

**lib/clock.rb**

[code]

    require 'clockwork'
    include Clockwork
    
    every(60.second, 'trade_limit_end_item_check.job') do
       puts `rake item:trade_limit_end_item_check`
    end
    
    
    every(300.second, 'limit_day_check.job') do
      puts `rake item:limit_day_check`
    end
    
[/code]


CC BY-SA 3.0
2015-05-28T08:51:10.760
10718
2015-06-05T05:32:07.997
2015-05-29T01:18:36.413
9161
9161
question
ruby-on-rails clockwork
Rails 4.2 rollback transaction


ログを見る限り `if no_check_item.count > 0` が常に `false`
になって更新処理（ifブロックの中身）が全く走っていないように見えますね。

rails console等で

[code]

    Item.where(limit_day: Time.mktime(2014, 12, 24, 00, 00, 00).prev_year..Time.now, trade: false, limit_check: false)
    
[/code]

が1件以上のデータを返すか確認してみてください。

また更新処理が走らないのであればトランザクションは大した意味を持たないので、commitされようが、rollbackされようが特に気にする必要は無いと思います。


CC BY-SA 3.0
2015-05-29T11:49:14.277
10766
2015-05-29T11:49:14.277
85
10718
answer

[code]

    transaction do
    ...
    end
    
[/code]

の中では例外が起こった時点でrollbackします。  
なので、私がtransactioinを行うときは下記のようにしています。

[code]

    begin
      transaction do
        no_err = true
        @item = Item.new(params[:item])
        no_err = @object.save
    
        @order = Order.find_by(id: params[:order][:id])
        no_err = @order.update_attributes(params[:order])
    
        raise unless no_err
      end
    rescue => e
      p e
      p @item.errors
      p @order.errors
    else
      #...
    end
    
[/code]

上記のように例外処理の中でインスタンスのerrorsを確認するようにして  
デバッグしてみるのはいかがでしょう。


CC BY-SA 3.0
2015-06-05T05:32:07.997
10997
2015-06-05T05:32:07.997
3884
10718
answer