【问题标题】:Rails transaction don't rollbackRails 事务不回滚
【发布时间】:2013-12-15 07:51:27
【问题描述】:

我有一个从 xml 文件客户加载的方法。在文件下载之前,所有不在 xml 文件中的客户都被放入有效性 false。然后开始加载和更新现有客户。我将整个方法包装在一个事务中。但是如果你故意让下载客户端出错(它没有通过验证)我还没有将整个事务回滚。提示我做错了什么?如何在事务轨道中工作?

代码:

if customers_upload
  EXCHANGE_LOGGER.info("Start customers exchange")
  Customer.transaction do
    begin
      customers = xml.elements.to_a("//customer")

      customers_external_keys = []
      customers.each do |customer| 
        customers_external_keys << customer.elements['external_key'].text
      end          
      customers_false = Customer.where("external_key NOT IN (?)", customers_external_keys)
      customers_false.each do |customer_false|
        if customer_false.validity
          customer_false.update_attributes(validity: false)              
        end
      end
      EXCHANGE_LOGGER.info("#{customers_false.count} update validity in false")

      customers.each do |customer| 
        customer_name = customer.elements['name'].text
        customer_external_key = customer.elements['external_key'].text
        customer_address = customer.elements['address'].text
        customer_debt = customer.elements['debt'].text
        customer_db = Customer.find_by_external_key(customer_external_key)
        if !customer_db
          new_customer = Customer.create(name: customer_name, external_key: customer_external_key, address: customer_address, debt: customer_debt)
          EXCHANGE_LOGGER.info("#Create new customer #{customer_name}")
        else 
          if !customer_db.validity
            customer_db.update_attributes(name: customer_name, address: customer_address, debt: customer_debt, validity: true)
            EXCHANGE_LOGGER.info("#Change validity true and update customer #{customer_name}")            
          else
            customer_db.update_attributes(name: customer_name, address: customer_address, debt: customer_debt)
            EXCHANGE_LOGGER.info("#Update customer #{customer_name}")
          end        
        end
      end

    rescue => e
      if e.present?
        EXCHANGE_LOGGER.error("Customers not exchanged, message: #{e}")
        raise ActiveRecord::Rollback, "Call tech support!"
      end          
    end        
  end  
end

以下是exchange.log中的内容:

2013-11-29 10:53:23 INFO Start customers exchange
2013-11-29 10:53:33 INFO 3981 update validity in false
2013-11-29 10:53:33 ERROR Customers not exchanged, message: undefined method `text 'for nil: NilClass

这里是内容 development.log:

 

 客户存在 (0.2ms) SELECT 1 AS one FROM customers WHERE (customers.External_key = 'CB001820' 和customers.Id! = 3979 ) 限制 1    (0.1ms) 更新customers SET validity = 0, updated_at = '2013-11 -29 10:53:33'在哪里customersId = 3979 客户存在 (0.2ms) SELECT 1 AS one FROM customers WHERE (customers.External_key = 'CB001826' 和customers.Id! = 3980 ) LIMIT 1    (0.1ms) 更新customers SET validity = 0 , updated_at = '2013-11 -29 10:53:33'在哪里customersId = 3980 客户存在 (0.2ms) SELECT 1 AS one FROM customers WHERE (customers.External_key = 'CB001822' AND customers.Id! = 3981 ) LIMIT 1    (0.1ms) 更新customers SET validity = 0, updated_at = '2013-11 -29 10:53:33'在哪里customersId = 3981 (2.2ms) SELECT COUNT (*) FROM customers WHERE (external_key NOT IN ('12312'))    (0.1ms) 回滚

像 ROLLBACK 出现在最后,但所有客户端仍然有效:(

【问题讨论】:

  • 忘记更改类型 tablin Inno_DB :)

标签: ruby-on-rails transactions rollback raise


【解决方案1】:

您必须在数据库中使用支持事务的表。例如 InnoDB

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-26
    • 2013-01-17
    • 2016-12-19
    • 2011-09-19
    • 2015-04-23
    相关资源
    最近更新 更多