Rails事务及事务嵌套

浏览:3076 发布日期:2016-06-27 03:47:29

Rails 事务及事务嵌套

Rails的事务,通过异常来决定是否需要回滚,其中抛出ActiveRecord::Rollback异常将只回滚,不抛出异常。

假如是嵌套事务,例如:

begin
    ActiveRecord::Base.transaction do 
        User.create(:name => "java")
        ActiveRecord::Base.transaction do
            User.create(:name => "c#")
            #raise "抛出异常==!" 
            raise ActiveRecord::Rollback
        end
    end
rescue => e
    puts "输出异常信息, #{e.message}"
end

两条记录都会插入,子事务的语句会被合并到父事务,由于并未引发异常,导致两条记录都被插入。

再比如:

begin
    ActiveRecord::Base.transaction do 
        User.create(:name => "java")
        ActiveRecord::Base.transaction do
            User.create(:name => "c#")
            raise "抛出异常==!" 
            #raise ActiveRecord::Rollback
        end
    end
rescue => e
    puts "输出异常信息, #{e.message}"
end

两条记录都不会被插入,都会回滚,虽然子事务被合并到父事务中,单抛出异常,导致父事务被回滚。

transaction类方法,有一个requires_new的参数,当这个参数为true,子事务语句不会合并到父事务中,当抛出异常,子事务回滚,异常向上传递,导致父事务也会回滚。不过,如果子事务使用raise ActiveRecord::Rollback,子事务只会混滚到事务记录点,即子事务回滚,父事务继续执行,例如:

begin ActiveRecord::Base.transaction do User.create(:name => "java") ActiveRecord::Base.transaction do User.create(:name => "c#") raise ActiveRecord::Rollback end end rescue => e puts "输出异常信息, #{e.message}" end

第一条记录会被插入,而第二条被回滚了。