MySQL中死锁情况的细节和死锁的处理

MySQL中死锁情况的细节和死锁的处理
死锁时产生多个事务的把握和要求对同一资源的锁并产生循环依赖。死锁发生在交易尝试锁定资源以不同的顺序。两交易对股票价格表为例:

交易1

开始交易;
股价紧贴= 45.50,更新stock_id = 4日= '2002-05-01;
股价紧贴= 19.80,更新stock_id = 3日= '2002-05-02;
承诺;
交易# 2

开始交易;
更新股票价格高= 20.12 = 3 = '2002-05-02 stock_id日期
更新股票价格设定;
承诺;
如果不幸的话,每个事务都可以执行第一个语句并将资源锁定在进程中。每个事务在试图被锁定时执行第二行语句。除非有其他原因来中断死锁,否则两个事务将一直等待另一个语句完成。

为了解决这个问题,数据库实现各种死锁检测和超时机制。一个复杂的存储引擎,如InnoDB会提示循环依赖并返回一个错误立即。否则,僵局会导致查询很慢。其他一些不好的做法是等待时间放弃。目前InnoDB处理死锁的方式是回滚事务持有最少的行级锁。(几乎为回滚最简单的参考

锁的行为是由存储引擎决定的,因此,一些存储引擎可能在特定的操作顺序中处于死锁状态,而另一些则可能不存在。死锁有两种:一些是不可避免的,因为实际的数据冲突,有些是由于存储引擎工作方式造成的。

只有一个事务的部分或全部回滚才能打破死锁。死锁是事务系统中的一个客观事实,在设计中您必须考虑处理死锁。一些业务系统可以从头开始重试事务。

如何处理死锁

死锁是事务数据库的典型问题,但除非经常发生,否则您甚至不能运行事务。他们一般都没有危险。通常情况下,你必须写让他们随时准备补发交易如果你回滚事务因为死锁的应用程序

InnoDB使用自动行级锁。即使在只有插入或删除一行交易的情况下,你可能会遇到一个僵局。这是因为这些操作是不是最小的,他们设置自动锁上(可能是几个),插入或删除的行的索引记录。

您可以使用以下技术来处理死锁,以减少它们发生的可能性:

使用SHOW INNODB STATUS来确定最后的僵局的原因。这有助于你调整应用程序以避免死锁。

随时准备补发交易如果失败因为死锁,死锁是不危险的,再试一次。

经常提交你的业务,小事情往往少一些冲突。

如果您正在使用锁读,请选择…更新或…锁定共享模式),尝试使用较低的隔离级别,如读提交。

以固定的顺序访问表和行。事务形成一个定义良好的查询,并且没有死锁。

在您的表中添加一个精心挑选的索引。您的查询需要扫描较少的索引记录,从而设置更少的锁。

使用更少的锁定。如果您可以接受一个选择允许从旧快照返回数据,则不添加更新或锁定共享模式子句。最好在这里使用读提交隔离级别,因为同一事务中的每一个连续读取都是从它自己的新快照中读取的。

如果没有其他的事是有帮助的,使用表级锁序列化你的交易。使用锁表的事务表的正确方式(如InnoDB)是设置自动提交= 0和叫不解锁表直到你明确提交事务。例如,如果你需要写表T1阅读从表中,你可以按如下做:
设置自动提交= 0;

锁定表t1写入,T2读取,…;

{在这里做表T1和T2的事情};

承诺;

打开表;

表级锁定使事务排队良好,避免死锁。

领导一个序列化的交易方式是创建一个辅助信号量表,其中只包含一个单一的线。让每个事务在访问其他表更新线。这样,所有的交易都发生在一个序列。注意,InnoDB即时死锁检测算法也可以租住在这种情况下,因为序列化的锁定是行级锁,超时的方法,锁定MySQL表水平,必须解决死锁。

在应用程序中使用锁表的命令,如果autocommit = 1,MySQL不设置innodb表锁。
免责声明:本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,并请自行核实相关内容。本站不承担此类作品侵权行为的直接责任及连带责任。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕。
相关文章
返回顶部