【问题标题】:Database is getting locked when saving my record保存我的记录时数据库被锁定
【发布时间】:2020-12-06 04:29:06
【问题描述】:

我在尝试保存我的记录时发现数据库被锁定。我正在尝试在 Rails 中写一个简单的博客。拥有一个包含属性、标题、图像和内容的文章模型。我以前没有遇到过这个错误。我正在使用carrierwave作为图像上传器gem。请问,我做错了什么?

这是错误图片

图片上传文件

class ImageUploader < CarrierWave::Uploader::Base
  include CarrierWave::MiniMagick

  # Choose what kind of storage to use for this uploader:
  storage :file
  # storage :fog

  # Override the directory where uploaded files will be stored.
  # This is a sensible default for uploaders that are meant to be mounted:
  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

  # Create different versions of your uploaded files:
  version :full do
    process resize_to_fit: [650, 650]
  end

  version :thumb do
    process resize_to_fit: [200, 200]
  end

  # Add a white list of extensions which are allowed to be uploaded.
  # For images you might use something like this:
  def extension_whitelist
    %w(jpg jpeg png)
  end

end

文章模型

class Article < ApplicationRecord
  belongs_to :author, class_name: 'User'
  mount_uploader :image, ImageUploader

  validates_presence_of :title, :text
  
end

【问题讨论】:

  • 这能回答你的问题吗? Ruby: SQLite3::BusyException: database is locked:
  • 这不是因为我在发布此问题之前已经完成了解决方案
  • 帮自己一个忙,如果可以的话,使用一个真正的数据库,Postgres 与 Rails 配合得很好,Mysql 也很好,两者都很容易设置。
  • 谢谢。我做到了,它现在可以工作了

标签: ruby-on-rails sqlite activerecord carrierwave image-upload


【解决方案1】:

我不认为这是特定于 CarrierWave 的,而是您正在使用的 sqlite 数据库/控制器中的逻辑。首先,您在插入之前调用 sqlite 查询,而不是将它们包装在事务中。 current_user.articles 可能会调用 many select 语句,这取决于他们有多少文章可能会锁定 insert 语句,所以如果你想继续使用 sqlite,我会考虑改变它。

Sqlite 不利于并发访问的锁定。虽然它是一款很棒的软件,但应该使用更合适的 DBMS,如 MySQL,并且在 docker 容器中设置本地开发非常容易。如果您想省点麻烦并设置 MySQL,我在下面提供了一个小示例。

如果你想继续使用 sqlite,你应该在数据库上打开一个控制台并vacuum 它。我发现此类数据库膨胀的扩展开发,您应该回收一些未使用的空间,通常有助于提高性能。

最后,有时 sqlite 文件会锁定,认为幽灵进程正在向它们写入数据,而恢复数据库是解决此问题的一种方法。通过直接在数据库上运行一个简单的选择命令进行检查(如果你可以查看表单等中的数据,我认为这不会发生在你身上)但以防万一,如果命令返回 true 你可以使用以下命令转储 in bashecho '.dump' | sqlite3 xxx.db.locked | sqlite3 xxx.db.dumped

设置 MySQL 如果使用 bash,则将以下内容插入到相应的文件中并运行 docker-compose up

# Gemfile
gem 'mysql2'

# docker-compose.yml
mysql_repo:
  image: percona:5.7.25
  ports:
    - "3306:3306"
  environment:
    - MYSQL_ALLOW_EMPTY_PASSWORD=yes
    - MYSQL_DATABASE=machine_host
  volumes:
    - /var/lib/mysql

# database.yml
mysql_defaults: &mysql_default
  adapter: mysql2
  encoding: utf8mb4
  reconnect: false
  pool: 5
  username: root
  password:
  host: 0.0.0.0
  port: 3306
  socket: /tmp/mysql.sock

development:
  <<: *mysql_default
  database: repo_development

test:
  <<: *mysql_default
  database: repo_test

production:
  <<: *mysql_default
  database: repo_production

【讨论】:

  • 在我切换到 postgres 时更改数据库为我做了这件事
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-05
  • 1970-01-01
  • 1970-01-01
  • 2015-11-22
  • 2011-10-30
相关资源
最近更新 更多