Mysql2 ::错误:尝试锁定时发现死锁; 尝试重启事务:INSERT INTO

pan*_*ang 7 ruby mysql sql ruby-on-rails

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

Mysql2::Error: Deadlock found when trying to get lock; try restarting transaction: INSERT INTO `products`....
Run Code Online (Sandbox Code Playgroud)

代码如下:

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

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
Run Code Online (Sandbox Code Playgroud)

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

Siv*_*iva 14

我的猜测是你正在使用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
Run Code Online (Sandbox Code Playgroud)

或者有一些像transaction_query这样的宝石来处理MySQL死锁.