Ruby:SQLite3::BusyException:数据库被锁定:

Posted

技术标签:

【中文标题】Ruby:SQLite3::BusyException:数据库被锁定:【英文标题】:Ruby: SQLite3::BusyException: database is locked: 【发布时间】: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。 【参考方案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。 完成!

【讨论】:

以上是关于Ruby:SQLite3::BusyException:数据库被锁定:的主要内容,如果未能解决你的问题,请参考以下文章

Ruby 25 岁了!Ruby 之父说 Ruby 3 有望 3 倍提速

如何学习ruby?Ruby学习技巧分享

ruby Ruby脚本,看看是否用openssl编译了ruby

什么是ruby?

ruby和ruby ee

ruby入门知识:了解ruby历史及特性