php处理死锁,php – 如何在应用程序级别处理MySQL死锁情况?

博客讨论了在处理数据库事务时可能出现的失败情况,特别是死锁和隔离问题。作者建议,良好的事务代码应预期并处理失败,通过重试循环来解决这些问题。重试过程中应重新读取数据、撤销外部修改并重做操作。文章提出了一个包含3次重试的事务处理模板,并强调区分不同类型的SQL错误。如果3次重试后事务仍失败,则提示用户稍后重试。
摘要由CSDN通过智能技术生成

事务可能会失败.死锁是一个失败的情况,你可以在序列化级别中有更多的失败.交易隔离问题是一场恶梦.试图避免失败是我认为的坏方法.

我认为任何写得很好的交易代码都应该有效地为失败的交易做准备.

正如您已经看到录制查询并重播它们不是一个解决方案,当您重新启动事务时,数据库已移动.如果这是一个有效的解决方案,那么SQL引擎一定会为你做的.对我而言,规则是:

>重做您在交易中的所有阅读(您在外部读取的任何数据可能已更改)

>从以前的尝试中抛出所有内容,如果您在事务之外写入的东西(日志,LDAP,SGBD之外的任何内容),则应该由于回滚而被取消

>重做所有事实:-)

这意味着重试循环.

所以你有你的try / catch块里面的事务.您需要添加一个可能3次尝试的while循环,如果代码的提交部分成功,则保留while循环.如果在3次重试之后,事务仍然失败,然后向用户启动异常 – 以便您不要尝试无限次的重试循环,事实上您可能会遇到一个非常大的问题.请注意,您应该以不同的方式处理SQL错误和锁定或可序列化异常. 3是一个任意数字,你可以尝试更多的尝试次数.

这可能会给出这样的东西:

$retry=0;

$notdone=TRUE;

while( $notdone && $retry<3 ) {

try {

$transaction->begin();

do_all_the_transaction_stuff();

$transaction->commit();

$notdone=FALSE;

} catch( Exception $e ) {

// here we could differentiate basic SQL errors and deadlock/serializable errors

$transaction->rollback();

undo_all_non_datatbase_stuff();

$retry++;

}

}

if( 3 == $retry ) {

throw new Exception("Try later, sorry, too much guys other there, or it's not your day.");

}

这意味着所有的东西(读,写,fonctionnal的东西)必须包含在$do_all_the_transaction_stuff()中.实施事务管理代码在控制器中,即高级应用程序功能主代码,不分为几个低级数据库访问模型对象.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值