对不起,这是一个非常笼统的问题,但我会尽量缩小范围。
我是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。
答案 0 :(得分:1)
自我注意:确保所有表都使用支持事务的引擎。虚设。
答案 1 :(得分:0)
我建议使用mysqli或PDO函数而不是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();