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

时间:2011-08-22 23:09:49

标签: ruby-on-rails sqlite

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

我有两种模式:

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

创建播客:

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

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

我认为以下before_validation方法会在我们创建新播客时自动创建所有关联的曲目。

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问题。我可以发布更多代码,如果有帮助的话。

18 个答案:

答案 0 :(得分:60)

对于其他任何人在Rails控制台打开时遇到SQLite锁定开发问题的问题,试试这个:

只需运行以下内容:

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

无论如何,它似乎清除了控制台所持有的任何事务并释放了数据库。

在运行delayed_job时,这对我来说尤其是个问题,因为它经常在关闭事务时失败。

答案 1 :(得分:22)

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

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

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

答案 2 :(得分:21)

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

答案 3 :(得分:14)

我有相同的“ActiveRecord :: StatementInvalid:SQLite3 :: BusyException:数据库被锁定:INSERT INTO”users“(”created_at“,”email“,”name“,”password_digest“,”updated_at“)VALUES( ?, ?, ?, ?, ?)“ 问题。我尝试了谷歌的各种方式,但我失败了。当我关闭我的SQLite数据库浏览器时,问题就解决了。

答案 4 :(得分:5)

确保没有2个警卫或多个控制台在运行。 如果你想确保拼命看到上面的“无名字”答案。

您也可以尝试增加游泳池:

例如: 在config / database.yml中更改测试部分,如下所示

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

答案 5 :(得分:2)

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

答案 6 :(得分:1)

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

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

"kill -9 [rails-pid]"

杀死进程。

然后它会起作用

答案 7 :(得分:1)

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

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

答案 8 :(得分:1)

我的麻烦是:我为SQlite&#34;打开了一个名为&#34;数据库浏览器的数据库管理程序。关闭了这个数据库管理程序,问题解决了。

答案 9 :(得分:0)

并行化测试时,您可能还启用了线程。请记住禁用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

答案 10 :(得分:0)

尝试在单笔交易中自动换行:

  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

答案 11 :(得分:0)

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

答案 12 :(得分:0)

尝试重新启动服务器 或关闭任何运行的rails控制台, 为我工作

答案 13 :(得分:0)

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

答案 14 :(得分:0)

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

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

答案 15 :(得分:0)

SQLite在并发方面遇到了麻烦。 我在Postgresql上更改了sqlite,问题就消失了

答案 16 :(得分:0)

我有同样的问题。对于那些使用SQLite Database Browser的人。我不需要关闭SQLite数据库浏览器。我只需要点击&#34;写更改&#34;按钮。它突出显示,不需要突出显示。

答案 17 :(得分:0)

是的,这是一个老问题,这里有很多答案。但它们都没有为我工作,这意味着我花了很长时间才弄清楚问题。 我发现了什么有效并将分享它,以防它可能导致您的问题。

我使用的是SQLITE浏览器(它是一个GUI数据库浏览器)。我将其称为&#34; GUI&#34;这里(以防止混淆浏览器这个词是你的localhost :: 8000 chrome浏览器或其他什么 http://sqlitebrowser.org/

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

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

事实证明,SQLite浏览器实际上并没有删除行(导致我的结果混淆为什么我的应用程序表现得像行仍然存在,即使它在视觉上缺失在GUI上)。无论如何,在30分钟的挫折之后,我关闭了SQLite GUI,然后收到通知,询问我是否要保存对我所做的数据库的任何更改。 我天真地点击了#34;否&#34; 并关闭了该应用。

显然会发生什么,然后GUI会锁定数据库,因为我的数据库中有些行已被软删除&#34;没有提交删除。因此,GUI(在缺乏一个更好的术语)将数据库保存在Limbo中。

这解释了为什么 a)我的应用程序并没有像行丢失一样,因为它还没有被删除,而 B)解释了为什么数据库已锁定。它还在等我提交删除。

所以为了解决这个问题,我只是再次打开GUI并删除了同一行,然后关闭了GUI,这点我点击的时间&#34;是&#34;当要求保存对数据库的更改时。它保存了删除并解锁了数据库,现在我的应用程序正常运行!

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