У меня есть метод, который загружается из 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
SETvalidity
= 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 мс) UPDATEcustomers
SETvalidity
= 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 мс) UPDATEcustomers
SETvalidity
= 0,updated_at
= '2013- 11 -29 10:53:33' ГДЕcustomers
.Id
= 3981 (2.2ms) SELECT COUNT (*) FROMcustomers
WHERE (external_key НЕ В ('12312')) (0,1 мс) откатить
Like ROLLBACK появляется в конце, но все клиенты будут по-прежнему остается в силе:. (
Забыл изменить тип tablin Inno_DB :) – galievruslan