繁体   English   中英

PHP中的数据库事务回滚处理

[英]database transaction rollback processing in PHP

try
{
  $con->beginTransaction();

  $this->doSave($con);

  $con->commit();
}
catch (Exception $e)
{
  $con->rollBack();

  throw $e;
}

上面的代码是处理交易的非常标准的方法,

但是我的问题是:如果$con->rollBack()也失败了怎么办?

可能会导致数据库锁定,对吗?如果是这样,什么是理想的选择?

使用事务时,基本思想是在调用commit之前,不会有任何东西真正永久地写入数据库。

几种情况:

  • 如果你 :
    • 开始交易
    • 执行一些查询
    • 回滚
    • 然后查询被回滚; 这意味着它们的结果未写入数据库。
  • 如果你 :
    • 开始交易
    • 执行一些查询
    • 断开连接(如果你的PHP脚本结束这恰好-例如,因为一个致命错误或的die
    • 然后,不提交查询-这意味着它们不会被写入数据库; 这意味着就像发生了rollback


简单地说:从begin transaction ,直到您commit ,所有内容都不会永久写入数据库。 如果没有提交,则不会永久写入任何内容,并且当您的PHP脚本与数据库断开连接时,数据库会“取消”该PHP脚本未提交的内容。

当然,如果您使用的是PHP以外的其他东西来连接数据库,则这完全相同-例如,命令行MySQL客户端。

MySQL通过回滚事务本身来处理错误情况。

回滚可能是一个缓慢的操作,可能会隐式发生,而无需用户明确要求(例如,发生错误时)。

MySQL文档涵盖了您的“假设情况”

如果禁用了自动提交的会话在没有显式提交最终事务的情况下结束,则MySQL将回滚该事务。

进一步:

提交和回滚都将释放在当前事务期间设置的所有InnoDB锁。

编辑:我为您的建议情况进行了测试。 在MySQL 5中使用innoDB表。

$db = new DB();
$db->beginTransaction();
$db->exec("INSERT INTO `table` (`val`) VALUES('commit?')");
sleep(30);
$db->commit();

正如我在下面的评论中所描述的那样。 如果允许完成,则在30秒后将事务提交到表。

如果我在允许脚本完成之前将其杀死,则事务将回滚,并且表将保持干净状态-如预期的那样。

使用事务数据库引擎,例如InnoDB 如果在写入过程中查询失败,这将保证数据完整性。 MySQL默认使用MyISAM引擎,该引擎速度更快且不具有事务性。 您需要做的就是在创建数据库时更改存储引擎。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM