Mysql 了解如何在InnoDB中处理死锁及其回滚

Mysql 了解如何在InnoDB中处理死锁及其回滚,mysql,transactions,innodb,database-deadlocks,Mysql,Transactions,Innodb,Database Deadlocks,过去我主要使用MyISAM作为存储引擎,直到最近才使用InnoDB更多;现在我真正开始使用InnoDB的锁定和隔离级别 我一直在读这本书,我关心的一件事是: InnoDB自动检测事务死锁并回滚一个或多个事务以打破死锁 所以换句话说,一些本来应该运行的代码因为死锁而被回滚,而您的数据完整性突然中断,因为所说的代码没有运行 即: 通常,您必须编写应用程序,以便在事务因死锁而回滚时,它们始终准备重新发出事务 问题是它没有解释如果查询因死锁而失败,如何重新发出查询或测试 在我看来,这是一个非常重要的问题

过去我主要使用
MyISAM
作为存储引擎,直到最近才使用
InnoDB
更多;现在我真正开始使用InnoDB的
锁定
隔离级别

我一直在读这本书,我关心的一件事是:

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

所以换句话说,一些本来应该运行的代码因为死锁而被回滚,而您的数据完整性突然中断,因为所说的代码没有运行

即:

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

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

在我看来,这是一个非常重要的问题,您希望运行的一些代码(将执行的查询)可能会回滚,而不会重新发布),而无需投入额外的代码来避免这种情况。这不是自动的吗

那么,有人能在这里向我解释一下处理这个问题的最佳方法是什么,或者我是否误解了什么

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

对。因此,您的下一个报价需要重新运行。重新运行事务涉及到一些问题,您的代码需要返回到
开始事务
,然后重试。重新发行不是自动的;你确实需要额外的代码

即使在
BEGIN
COMMIT
上,也要确保检查错误

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

小心不要进入无限循环。(例如,如果您“循环直到无错误”,并且错误不是“死锁”,例如“连接丢失”。)

如果一次连接的用户不超过一个,则不可能出现死锁,但也可能出现其他错误,有些是暂时的


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

因此,如果我想重新发布它们,我只需在循环中运行查询x次,或者直到成功为止?是的。我推荐2-3次,然后给出一个致命错误。如果第二次尝试没有成功,那么可能是因为某种原因而不是简单的死锁导致了问题,您需要对此进行调查。