【问题标题】:SQLite3::BusyException: database is locked: INSERT INTOSQLite3::BusyException:数据库被锁定:INSERT INTO
【发布时间】:2017-02-07 22:50:50
【问题描述】:

当我通过任务运行这段代码时,它可以工作

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 模型中的一个函数中。 导入从浏览器启动,GET 路由到调用模型导入函数的控制器 导入完成后,应将完整的记录列表返回到视图。 csv 文件有 4k 行。 导入过程需要时间,并且似乎在 60 秒后重新发送 GET。 有人能解释一下如何避免重新发送导致导入崩溃吗?

【问题讨论】:

    标签: ruby-on-rails sqlite


    【解决方案1】:

    将其包装在事务中将确保所有查询将一起运行,而不是一次运行 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

    【讨论】:

    • 谢谢!它的工作原理知道。这种重新发送 GET 的超时怎么办?有没有办法避免这种情况?
    • 我不知道,我不认为服务器控制即客户端?不过我不确定。该操作现在只需不到 60 秒,对吧?
    • 是的,但如果我需要上传较大的文件?我想知道它是否来自浏览器。并且在这种情况下,是否可以测试数据库繁忙以避免冲突的事实
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-01
    • 2015-06-05
    • 2023-03-26
    • 2015-11-22
    • 1970-01-01
    相关资源
    最近更新 更多