如何在PHP中使用MySQL事务?

时间:2010-08-26 05:38:20

标签: php mysql transactions

对不起,这是一个非常笼统的问题,但我会尽量缩小范围。

我是MySQL / PHP中这个整个事务的新手但看起来很简单。我只是使用mysql而不是mysqli或PDO。我有一个脚本似乎回滚了一些查询而不是其他查询。这对我来说是一个未知的领域,所以我不知道发生了什么。

我用mysql_query('START TRANSACTION;')启动事务,据我所知,它同时禁用了自动提交。然后我有很多复杂的代码,每当我进行查询时,它都是这样的mysql_query($sql) or $error = "Oh noes!"。然后定期我有一个名为error_check()的函数,它会检查$error是否为空,如果不是,我会mysql_query('ROLLBACK;')die($error)。稍后在代码中我mysql_query('COMMIT;')。但是如果我做两个查询然后故意抛出一个错误,我的意思是设置$ error = something,看起来第一个查询回滚但第二个查询不回滚。

可能出现什么问题?是否有一些我不知道的交易陷阱?我不太清楚这些事务是如何开始和停止的,尤其是当你将PHP混合在一起时......

修改 我的示例过于简化了我实际上至少有两个事务在不同的表上执行INSERT,UPDATE或DELETE。但在执行每个语句之前,我会备份相应“历史”表中的行以允许撤消。看起来主表的操作被回滚,但历史表中的条目仍然存在。

EDIT2: 卫生署!当我完成上一次编辑时,它突然出现在我身上......那些特定的表肯定有问题......出于某种原因,它们都被设置为MyISAM。

3 个答案:

答案 0 :(得分:1)

自我注意:确保所有表都使用支持事务的引擎。虚设。

答案 1 :(得分:0)

我建议使用mysqliPDO函数而不是mysql,因为它们提供了一些有价值的改进 - 尤其是使用prepared statements

如果没有看到您的代码,很难确定问题所在。鉴于您说您的代码很复杂,问题可能在于您的代码而不是MySQL事务。

您是否尝试过创建一些独立的测试脚本?也许您可以从应用程序中隔离SQL语句,并创建一个简单的脚本,只需将它们串行运行即可。如果可行,您可以缩小问题的根源。您可以回应应用程序中的SQL语句以获取正在运行的命令。

您也可以尝试从MySQL客户端或通过PHPMyAdmin测试相同的SQL语句序列。

您的历史记录表是否在同一个数据库中?

答案 2 :(得分:0)

Mysql事务只能使用mysqli API(不是经典方法)。我一直在使用交易。我所做的只是停用自动提交并运行我的SQL语句。

$mysqli->autocommit(FALSE);

支持SELECT,INSERT,DELETE all。只要我使用相同的mysqli句柄来调用这些语句,它们就在事务包装器中。只要事务仍处于打开状态,外部没有人(不使用相同的mysqli句柄)将看到使用INSERT / DELETE编写/删除的任何数据。因此,关键是要确保每个SQL语句都使用该句柄触发。提交事务后,数据可供其他数据库连接使用。

$mysqli->commit();