数据库 初级问题,AR transaction 怎么用怎么看效果

as181920 · 2013年04月21日 · 最后由 jimmy85 回复于 2013年05月24日 · 3377 次阅读

简单如下

class Ma < ActiveRecord::Base
end

class Mb < ActiveRecord::Base
end


class Mc < ActiveRecord::Base
  def xxx
    transaction do
      Ma.create attr1: "xxx"
      raise "error"
      Mb.create attr1: "xxx"
    end
  end
end

大致如上,没贴细节代码,在 transaction 中间 raise 了,但是数据库 Ma 还是多了一条记录,为何

你的数据库不支持事务吧?

#1 楼 @quakewang apt install 的 postgresql

#1 楼 @quakewang 我在 console 下测试了用 transaction 这样使用是有用的,应该是我代码细节问题,我自己看吧,Thx

去看 development.log,关注里面的 BEGIN, COMMIT, ROLLBACK.

#4 楼 @yanhao 从 log 看,在 rollback 前居然有个 commit 操作,不知怎么回事

D, [2013-04-21T15:32:34.024600 #15630] DEBUG -- :    (0.3ms)  BEGIN
D, [2013-04-21T15:32:34.096260 #15630] DEBUG -- :    (0.6ms)  BEGIN
D, [2013-04-21T15:32:34.104295 #15630] DEBUG -- :   SQL (2.8ms)  INSERT INTO "records" ("note_id") VALUES ($1) RETURNING "id"  [["note_id", 338]]
D, [2013-04-21T15:32:34.125080 #15630] DEBUG -- :    (20.0ms)  COMMIT
D, [2013-04-21T15:32:34.127409 #15630] DEBUG -- :    (0.7ms)  ROLLBACK

log 如上 代码如下

module MnModel
  class Note < ActiveRecord::Base
    establish_connection DB_CONFIGURATIONS

    has_many :fields
    has_many :records
    has_many :items, through: :fields

    def create_record_with_date(attributes={})
      record_with_data = {}

      transaction do
        record = Record.create note_id: id
        record_with_data.merge! record.serializable_hash

        raise "error"
        fields.each do |f|
          item = Item.create record_id: record.id, field_id: f.id, content: attributes[f.name]
          record_with_data.merge!(f.name => item.content)
        end
      end

      return record_with_data
    rescue => e
      return {}
    end
  end
end

看 log 是 create 本身就有了一个 begin/commit,再外面的 transaction 的 rollback 已经没效果了?

ps:ruby+activerecord;不在 rails 中

用 create! 试试

发现一个小坑,表名不能用 records,这个是保留单词,容易引起问题。

呵呵,学习了

需要 登录 后方可回复, 如果你还没有账号请 注册新账号