Mysql2::错误:尝试获取锁时发现死锁;尝试重新启动事务:INSERT INTO

标签 mysql sql ruby-on-rails ruby

最近,我在我的应用程序中发现了很多死锁错误。

Mysql2::Error: Deadlock found when trying to get lock; try restarting transaction: INSERT INTO `products`....

代码如下:

创建用户后,我将向用户添加一些产品。我不明白为什么会发生死锁。

class User < ActiveRecord::Base
    after_create :add_products
    has_many :products, :dependent => :destroy

    def self.create_user
      User.create!(.......)
    end

    def add_products
      Product.add(self, "product_name", 10)
    end
    .....
end

class Product < ActiveRecord::Base
    belongs_to :user

    def self.add(user, product_name, amount)
       transaction do
         product = user.products.find_by_product_name(product_name)
         if product
            product.increment :amount, amount
            product.save!
         else
            product = self.create! user_id: user.id,
                                   product_name: product_name,
                                   amount: amount
         end
       end
       product
    end
end

我没有找到根本原因,谁能给我一些建议?提前致谢!!!

最佳答案

我的猜测是您正在使用 InnoDB 并且可能正在执行并发插入。

要追踪和了解原因,请查看这些文章:

解决该问题的一种方法是重试,如下面的代码所示:

def add_products
    retries = 0

    begin
        Product.add(self, "product_name", 10)
    rescue  ActiveRecord::StatementInvalid => ex
        if ex.message =~ /Deadlock found when trying to get lock/ #ex not e!!
            retries += 1   
            raise ex if retries > 3  ## max 3 retries 
            sleep 10
            retry
        else
            raise ex
        end
    end
end

或者,有一些 gem ,如 transaction_retry处理 MySQL 死锁。

关于Mysql2::错误:尝试获取锁时发现死锁;尝试重新启动事务:INSERT INTO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27246003/

相关文章:

python - 如何使用 Python 对 SQL IN 子句进行字符串格式化

javascript - 为什么在 Coffeescript 中创建 AngularJS Controller 时使用 @ 符号?

ruby-on-rails - rails : Rake Test:functionals cannot access DB (Sqlite3 on winXP)

sql - 根据日期和月份的出现情况生成日期列表

mysql - SQL 如果 A 列存在且等于 B 则从 all 中删除所有

sql - 使用 SQL Server 在 Linux 上运行目录中的所有 .sql 文件

CSS 未在 heroku Hartl Ch 10 中加载

mysql - 安装 MySQL 工作台

更新后,MySQL 服务器将无法使用 'mysqld' 从终端启动

PHP Foreach 循环 - 在不同的数组中搜索数组的值,如果存在则进行数学计算