2013-11-29 3 views
0

У меня есть метод, который загружается из xml-файлов клиентов. Перед загрузкой файла все клиенты, которые не находятся в xml-файле, помещаются в значение false. Затем начинается загрузка и обновление существующих клиентов. Я завернул весь метод в транзакцию. Но если вы попытаетесь сделать клик загрузки намеренно неправильным (который не проходит проверку), у меня не будет откат всей транзакции. Подскажите, что я делаю неправильно? Как работать в рельсах транзакций?Rails транзакция не откат

Код:

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) ВЫБЕРИТЕ 1 КАК один ОТ customers ГДЕ (customers. External_key = 'CB001820' И customers. Id! = 3979) LIMIT 1 (0,1 мс) ОБНОВЛЕНИЕ customers SET validity = 0, updated_at = '2013- 11 -29 10:53:33' ГДЕ customers. Id = Exists 3979 клиентов (0,2 мс) выберите 1 в качестве одного ИЗ customers ГДЕ (customers. External_key = 'CB001826' И customers. Id! = 3980) ЛИМИТ 1 (0,1 мс) UPDATE customers SET validity = 0, updated_at = '2013- 11 -29 10:53:33' ГДЕ customers. Id = Exists 3980 клиентов (0,2 мс) выберите 1 в качестве одного ИЗ customers ГДЕ (customers. External_key = 'CB001822' И customers. Id! = 3981) ЛИМИТ 1 (0,1 мс) UPDATE customers SET validity = 0, updated_at = '2013- 11 -29 10:53:33' ГДЕ customers. Id = 3981 (2.2ms) SELECT COUNT (*) FROM customers WHERE (external_key НЕ В ('12312')) (0,1 мс) откатить

Like ROLLBACK появляется в конце, но все клиенты будут по-прежнему остается в силе:. (

+0

Забыл изменить тип tablin Inno_DB :) – galievruslan

ответ

0

Вы должны использовать таблицы в базе данных, которая поддерживает транзакцию, например InnoDB

Смежные вопросы