ActiveRecord3死锁重试

12

是否有适用于Rails 3 (或ActiveRecord 3)的插件,可以复制旧的deadlock_retry插件?那个插件还适用于Rails 3吗?

3个回答

10

我甚至不知道有一个插件可以做到这一点 :)

这是我们使用的方法(但您必须自己将可能导致死锁的查询封装在其中):

# Executes the given block +retries+ times (or forever, if explicitly given nil),
# catching and retrying SQL Deadlock errors.
def retry_lock_error(retries = 100, &block)
  begin
    yield
  rescue ActiveRecord::StatementInvalid => e
    if e.message =~ /Deadlock found when trying to get lock/ and (retries.nil? || retries > 0)
      retry_lock_error(retries ? retries - 1 : nil, &block)
    else
      raise e
    end
  end
end

1
这刚刚为我省了一场头疼。谢谢你。 - Sean McCleary

8

有一个transaction_retry宝石,它不仅适用于Rails 3+,而且支持所有主要数据库(MySQL,PostgreSQL和SQLite)。 它被推销为干净且经过充分测试。


嗯,最后一次提交是在2018年6月,但在此之前是在2013年6月。这是一个5年的时间窗口,在这段时间内没有对宝石进行任何操作。我持怀疑态度。很想听听是否有人在Rails 4+中已经成功地使用了它。 - Joshua Pinter
我们目前正在我们的Rails 4.2.11应用程序上尝试它,看起来运行得非常好。它完全解决了我们在密集并发导入期间遇到的死锁问题,并且据我们所知,似乎没有引起任何其他问题。 - Joshua Pinter

2

rails / deadlock_retry

死锁重试允许数据库适配器(目前仅测试过MySQLAdapter)在发生死锁时重试事务。它将在最终失败之前重试此类事务三次。

这种功能已自动添加到ActiveRecord中。不需要进行任何代码更改或其他更改。


关于“这种功能会自动添加到ActiveRecord”- 我正在尝试寻找确认此事的来源,但谷歌搜索无果。您能指向AR核心中描述此功能的地方吗? - Mark Nadig
1
我认为你可能误解了——帖子引用的宝石(rails / deadlock_retry)会自动将其添加到Active Record中。 - Jason FB

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接