我有一种从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.2毫秒)从
customers
WHERE(customers
。External_key
='CB001820'和customers
。Id
!= 3979)中选择1为1(0.1ms)UPDATEcustomers
SETvalidity
= 0,updated_at
='2013- 11 -29 10:53:33'WHEREcustomers
。Id
= 3979客户存在(0.2ms)从1处选择1customers
(customers
。External_key
='CB001826'ANDcustomers
。Id
!= 3980)LIMIT 1(0.1ms)UPDATEcustomers
SETvalidity
= 0,updated_at
='2013-11 -29 10:53:33'在哪里customers
。Id
= 3980客户存在(0.2ms)从1处选择1customers
(customers
。External_key
='CB001822'ANDcustomers
。Id
!= 3981)LIMIT 1(0.1ms)UPDATEcustomers
SETvalidity
= 0,updated_at
='2013- 11 -29 10:53:33'在哪里customers
。Id
= 3981(2.2ms)从customers
哪里选择计数(*)(external_key NOT IN('12312'))(0.1ms)回滚
就像ROLLBACK出现在末尾,但所有客户端仍将保持有效:(
您必须在数据库中使用支持事务的表。例如InnoDB
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句