【问题标题】:Ruby: SQLite3::BusyException: database is locked:Ruby:SQLite3::BusyException:数据库被锁定:
【发布时间】:2011-11-01 13:13:14
【问题描述】:

今晚开发时遇到此错误消息:SQLite3::BusyException: database is locked:

我有两个模型:

  • 播客有很多曲目
  • 曲目属于播客。
  • 播客文件托管在mixcloud

创建播客:

  • 用户在 mixcloud 上提交播客的网址
  • rails 应用抓取与 url 关联的 json 提要
  • json 用于设置新 Podcast 对象的属性(标题、图像等)

我正在尝试让我的 rails 应用程序利用 json 提要还详细说明属于此 Podcast 的曲目的名称(和艺术家)这一事实。

我认为以下 before_validation 方法会在我们创建新 Podcast 时自动创建所有关联的 Track。

class Podcast < ActiveRecord::Base
  attr_accessible :mixcloud_url, :lots, :of, :other, :attrs
  has_many :tracks    
  before_validation :create_tracks
  def create_tracks
    json = Hashie::Mash.new HTTParty.get(self.json_url)    
    json.sections.each do |section|
      if section.section_type=="track"
          Track.create(:name=>section.track.name, :podcast_id=>self.id)
      end
    end             
  end
end

我怎样才能解决这个问题?看起来rails(或sqlite3)不喜欢我以这种方式创建关联模型的新实例。我还能怎么做?我怀疑这与 sqlite3 一样是 rails 问题。如果有帮助,我可以发布更多代码。

【问题讨论】:

  • ps - 当我提交一个新的播客时会显示错误,我很确定我对提要的解析不是问题。
  • pps - :json_url 是在另外一个 before_validation 方法中设置的,我只是没提,确实工作正常
  • AFAIK sqlite 在操作数据时会锁定整个数据库文件(因为它是唯一的),所以您可能会遇到问题。 Sqlite 不适合有多个并发用户的应用程序使用。
  • 对我来说,问题是我打开了用于 SQLite 的 DB Browser。

标签: ruby-on-rails sqlite


【解决方案1】:

对于在 Rails 控制台打开时在开发中遇到 SQLite 锁定问题的任何其他人,请尝试以下操作:

只需运行以下命令:

ActiveRecord::Base.connection.execute("BEGIN TRANSACTION; END;")

无论如何,对我来说,它似乎清除了控制台保留的所有事务并释放了数据库。

在运行delayed_job 时,这对我来说尤其是个问题,它似乎经常无法关闭事务。

【讨论】:

  • 抱歉,我是 ruby​​ 和 rails 的新手,谁能解释一下我与这条线有什么关系?我无法在 cmd 中运行它...
  • 迟到了,但对于在上一条评论中与@AkshatSharda 有相同问题的任何人,只需在命令行中输入rails console,然后粘贴上面的 ruby​​ sn-p。
【解决方案2】:

SQLite 并不真正应该用于并发访问,这是您在这里遇到的问题。您可以尝试增加 database.yml 文件中的超时时间,在这种情况下,这可能是您的解决方法。但是,我建议您切换到另一个支持多个连接的数据库,例如 MySQL 或 PgSQL。

【讨论】:

  • 天哪,将超时更改为 3000000 解决了这个问题。我确实需要再次删除并迁移数据库,但只要它有效,我就很高兴。再次感谢。
  • 嗯,只是警告您这是一种不好的做法,并且确实建议您转移到常规数据库。但是对于开发来说,这应该没问题。
  • 是的,我在生产中(在 heroku 上)使用 PG,我怀疑这个问题会突然出现,我可以忍受 SQLite3 在开发模式下的限制。
  • 添加:timeout =&gt; 1000 选项解决了我的问题。我有并发访问,这个锁正在杀死我的应用程序。谢谢
【解决方案3】:

对我来说......我遇到的问题是,我打开了一段时间的 Rails 控制台似乎锁定了与 SQLite 的连接。

因此,一旦我退出该控制台并重新启动我的网络服务器(瘦),它就会完美运行。

我尝试了@trisweb 的建议,但对我不起作用。

【讨论】:

  • 我正准备发表此评论! +1
  • 与此类似,如果您在数据库上打开了 SQLite DB Browser 程序,则会遇到此问题。
  • 另外,如果你在你的 mac 上使用了 ctrl+d,使用 fg 将它带回前台并 ctrl+c 。
【解决方案4】:

我也一样

ActiveRecord::StatementInvalid: SQLite3::BusyException: 数据库是 锁定:插入“用户”(“created_at”,“电子邮件”,“名称”, "password_digest", "updated_at") VALUES (?, ?, ?, ?, ?)"

问题。我尝试了在 Google 中找到的所有方法,但都失败了。当我关闭我的 SQLite 数据库浏览器时,问题就解决了。

【讨论】:

    【解决方案5】:

    确保您没有运行 2 个守卫或多个控制台。 如果您想确保拼命查看上面的“无名”答案。

    您也可以尝试增加池:

    例如: 如下更改 config/database.yml 中的测试部分

    test:
        adapter: sqlite3
        database: db/test.sqlite3
        pool: 50
        timeout: 5000
    

    【讨论】:

      【解决方案6】:

      可能您在另一个 bash 上打开了一个 Rails 控制台,如果是这样,您必须关闭它 (ctrl+D)。

      【讨论】:

      • 不知道为什么这被否决,因为它绝对是可能的选项之一。
      • 这应该有更多的赞成票。至少对我来说这是解决方案。
      【解决方案7】:

      实际上对我来说,我发现杀死 rails 有助于解决这个问题。

      使用"ps aux | grep rails" 找出正在进行的rails 进程ID。 然后使用

      "kill -9 [rails-pid]"
      

      杀死进程。

      然后就可以了

      【讨论】:

        【解决方案8】:

        它很可能与 Rails 代码无关。同时使用带有沙盒选项的控制台 (rails console --sandbox),会使 SQLite 系统化问题,因为控制台基本上是在等待退出以回滚所有内容。

        @trisweb 的上述解决方案在这种情况下不起作用,但退出控制台会。

        【讨论】:

          【解决方案9】:

          我的麻烦是:我打开了一个名为“DB Browser for SQlite”的数据库管理程序。关闭了这个数据库管理程序,问题解决了。

          【讨论】:

          • 同样的问题
          【解决方案10】:

          是的,这是一个老问题,这里已经有很多答案了。但它们都不适合我,这意味着我花了很长时间才最终找出问题所在。 我找到了有效的方法并将分享它,以防它也可能给您带来问题。

          我使用的是 SQLITE 浏览器(它是一个 GUI 数据库浏览器)。我将在这里将其称为“GUI”(以防止与单词 browser 混淆为您的 localhost::8000 chrome 浏览器或其他任何内容。
          http://sqlitebrowser.org/

          我正在监视正在写入数据库的内容,并在我的 rails 应用程序在我的 chrome 浏览器中运行时打开了 GUI。我会刷新 GUI 以查看它是否按照我的预期添加数据。

          作为调试问题,我决定从 SQLite GUI 中删除一行,以便查看我的应用是否会对现在丢失的行做出适当的反应。

          事实证明,SQLite 浏览器 实际上并没有删除该行(这让我感到困惑,为什么我的应用程序表现得像该行仍然存在,即使它在视觉上丢失了在图形用户界面上)。无论如何,经过 30 分钟的挫折后,我关闭了 SQLite GUI,然后收到一条通知,询问我是否要保存对数据库所做的任何更改。 我天真地点击了“否”并关闭了应用。

          显然发生的情况是,GUI 随后锁定了数据库,因为我的数据库中的某些行在没有提交删除的情况下被“软删除”。因此,GUI (因为没有更好的术语)将数据库保存在 Limbo 中。

          这解释了为什么 a) 我的应用程序没有表现得像缺少行一样,因为它实际上还没有被删除,B) 解释了数据库锁定的原因向上。它仍在等待我提交删除。

          所以为了解决这个问题,我只是再次打开 GUI 并删除了同一行,然后关闭了 GUI,这当我要求保存对数据库的更改时单击“是” .它保存了删除并解锁了数据库,现在我的应用程序可以工作了!


          我希望这对可能遇到相同问题但使用 SQLite 浏览器 GUI 界面的其他人有所帮助。这可能是锁定数据库的原因。

          【讨论】:

            【解决方案11】:

            我遇到了同样的问题。对于那些使用 SQLite 数据库浏览器的人。我不需要关闭 SQLite 数据库浏览器。我只需要单击“写入更改”按钮。它被突出显示,不需要突出显示。

            【讨论】:

              【解决方案12】:

              SQLite 存在并发问题。 我在 Postgresql 上更改了 sqlite,问题就消失了

              【讨论】:

                【解决方案13】:

                当您直接在 SQlite DB 浏览器中手动进行任何更改(如删除一行或更改任何列的值)并忘记保存这些更改时,就会发生这种情况。所做的任何更改都需要保存 (ctrl + s)。如果未保存,SQLite 将锁定数据库,直到您保存这些更改。

                我做了同样的事情,我的问题得到了解决!

                【讨论】:

                  【解决方案14】:

                  我同时使用DB Browser for SQLite 和rails 控制台。关闭 DB Browser for SQLite 为我解决了这个问题。

                  【讨论】:

                    【解决方案15】:

                    尝试重启服务器 或关闭任何正在运行的 Rails 控制台, 为我工作

                    【讨论】:

                      【解决方案16】:

                      您的 .sqlite3 文件必须保存。 转到 DB Browser for SQlite 并进行 ctrl+s 或 File->Write Changes。

                      【讨论】:

                        【解决方案17】:

                        尝试在单个事务中包装循环:

                          def create_tracks
                            json = Hashie::Mash.new HTTParty.get(self.json_url)    
                            Track.transaction do
                              json.sections.each do |section|
                                if section.section_type=="track"
                                  Track.create(:name=>section.track.name, :podcast_id=>self.id)
                                end
                              end
                            end             
                          end
                        

                        (参见Track.transaction

                        【讨论】:

                          【解决方案18】:

                          在并行化测试时,您可能还启用了线程。记得禁用test/test_helper.rb中的选项:

                          parallelize(workers: :number_of_processors, with: :threads)
                          

                          parallelize(workers: :number_of_processors)
                          

                          https://edgeguides.rubyonrails.org/testing.html#parallel-testing-with-threads

                          【讨论】:

                            【解决方案19】:
                            1. bin/rails console 
                            2. exit
                            

                            进入 rails 控制台并输入 exit,然后按 enter。 完成!

                            【讨论】:

                              猜你喜欢
                              • 2017-02-07
                              • 1970-01-01
                              • 1970-01-01
                              • 2015-06-05
                              • 2023-03-26
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              相关资源
                              最近更新 更多