保存我的记录时数据库被锁定

问题描述

尝试保存记录时,数据库正在锁定。我正在尝试在Rails中创建一个简单的博客。有一个文章模型,其中包含属性标题,图像和内容。我之前没有遇到此错误。我正在将carrierwave用作图像上传器gem。请问我在做什么错了?

这是错误图像

enter image description here

图片上传文件

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

解决方法

我不认为这是特定于CarrierWave的,但是您正在控制器中使用/ sql的sqlite数据库更多。首先,在插入而不是将它们包装在事务中之前,先调用sqlite查询。 current_user.articles可能正在调用许多 select语句,具体取决于他们拥有多少篇文章,这些文章可能会锁定insert语句,因此如果您愿意,我将考虑对其进行更改继续使用sqlite。

Sqlite对于锁定并发访问非常有害。尽管它是一款很棒的软件,但应使用更合适的DBMS(如MySQL),并且在docker容器中进行本地开发的设置非常容易。如果您想减轻自己的痛苦并设置MySQL,我在下面提供了一个小示例。

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

最后,有时sqlite文件会锁定,以为正在向其写入幻影进程,而恢复数据库是解决此问题的一种方法。通过直接在数据库上运行一个简单的select命令进行检查(如果您可以查看表格等数据,我认为这不会发生),但以防万一,如果该命令返回true可以使用以下命令在 bash 中转储:echo '.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