2016-09-29 72 views
1

当我运行这段代码有一个任务,它的工作原理的SQLite3 :: BusyException:数据库被锁定:INSERT INTO

task :importGss => :environment do 
    Gss.delete_all 
    file = Rails.root + "app/assets/CSVs/gss.csv" 
    csv_text = File.read(file) 
    puts csv_text.size 
    csv = CSV.parse(csv_text, :col_sep => ';', :headers => true) 
    csv.each do |row| 
    Gss.create!(row.to_hash) 
end 

当我与一个MVC运行它,我有以下消息:

的ActiveRecord :: StatementInvalid(SQLite3的:: BusyException:数据库被锁定:

我在GSS模型把上面的代码中的函数 进口从具有获取浏览器被路由到启动。控制器调用模型导入功能 导入完成后,应将完整的记录列表返回到视图。 csv文件有4k行。 导入过程需要时间,并且似乎恰好在60秒后重新发送GET。 有人可以解释我如何避免这种重新发送导致崩溃导入?

回答

4

在事务中包装它将确保所有查询一起运行,而不是一次运行1次。这将大大减少为多行执行导入所花费的时间。

task :importGss => :environment do 
    Gss.delete_all 
    file = Rails.root + "app/assets/CSVs/gss.csv" 
    csv_text = File.read(file) 
    puts csv_text.size 
    csv = CSV.parse(csv_text, :col_sep => ';', :headers => true) 

    ActiveRecord::Base.transaction do 
     csv.each do |row| 
     Gss.create!(row.to_hash) 
     end 
    end 
end 

了解更多关于交易的位置:http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html

+0

谢谢!它的作品知道。这种重新发送GET的超时会怎么样?有没有办法避免这种情况? – user3239711

+0

我不知道任何,我不认为服务器控制,即客户端?虽然我不确定。这个动作现在不到60秒,但是正确吗? – RichardAE

+0

是的,但如果我需要上传啤酒文件?我不知道它是否来自浏览器。在这种情况下,是否有可能测试数据库繁忙以避免冲突的事实 – user3239711