【问题标题】:Understanding how to handle deadlocks and their rollbacks in InnoDB了解如何在 InnoDB 中处理死锁及其回滚
【发布时间】:2015-04-15 08:17:13
【问题描述】:

我过去主要使用MyISAM作为存储引擎,最近才更多地使用InnoDB;现在我正处于真正开始使用 InnoDB 的 lockingisolation levels 的地步。

我一直在阅读documentation,我担心的一件事是it states

InnoDB 自动检测事务死锁并回滚一个或多个事务以打破死锁。

换句话说,一些应该运行的代码由于死锁而被回滚,突然之间你的数据完整性就因为所说的代码没有运行!?

They also state那个:

通常,您必须编写应用程序,以便它们随时准备在事务因死锁而回滚时重新发出事务。

问题是它没有解释如何重新发出查询或测试它们是否因死锁而失败?

这在我看来是一个重大问题,即您希望运行的某些代码(执行查询)可能会被回滚而不是重新发出),而无需您添加额外的代码来避免这种情况。这不应该是自动的吗?

所以有人可以在这里向我解释处理此问题的最佳方法是什么,或者我是否误解了什么。

【问题讨论】:

    标签: mysql transactions innodb database-deadlocks


    【解决方案1】:

    由于死锁,一些本应运行的代码被回滚

    没错。因此,您的下一个关于需要重新运行的报价。重新运行事务涉及您的代码返回START TRANSACTION 并重试。重新发行不是自动的;你确实需要额外的代码。

    请务必检查错误,即使在 BEGINCOMMIT 上也是如此。

    至于代码是什么样子的……这取决于您使用的 API。有些已经有try/catch 语法;有些没有。

    注意不要陷入无限循环。 (例如,如果你“循环直到没有错误”,并且错误不是“死锁”,例如“连接丢失”。)

    如果您一次连接的用户不超过一个,死锁是不可能的,但其他错误(有些是暂时的)是可能的。

    至于isolation levels,我建议保持默认。只有当您进入高交易率并且正在做一些特殊的事情时,您才可能需要更改级别。

    【讨论】:

    • 所以如果我想重新发布它们,我只需在循环中运行查询 x 次或直到它成功?
    • 是的。我推荐2-3次,然后给出一个致命错误。如果第二次尝试没有成功,可能不是简单的死锁导致了问题,您需要调查它。
    猜你喜欢
    • 2011-07-15
    • 2013-12-09
    • 2013-05-27
    • 1970-01-01
    • 2013-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多