如果查询失败,是否有必要编写ROLLBACK?

时间:2010-05-01 18:40:31

标签: php mysql transactions

我写

mysql_query("SET AUTOCOMMIT=0");
mysql_query("START TRANSACTION");

在我写所有查询之前。然后检查它们是否都为真,然后写:

mysql_query("COMMIT");

但如果其中一个查询失败,我只是传递COMMIT查询。如果其中一个查询失败,我真的需要ROLLBACK函数吗?因为没有ROLLBACK它也有效 感谢。

5 个答案:

答案 0 :(得分:12)

我认为你问是否有必要执行ROLLBACK,因为没有它,提交仍然没有得到应用。这在技术上是正确的,但仅仅因为交易仍未结束,因为您尚未结束交易。任何隐式提交事务的东西(例如,启动一个新事务)都会像你运行COMMIT一样,这与你想要的相反

答案 1 :(得分:5)

使用事务的原因是将多个更改组合在一起,以便它们都以原子方式成功,否则如果不能,则不要执行任何更改。换句话说,如果任何更改失败,则事务将使数据库处于逻辑上不一致的状态。

示例:在一个UPDATE中借记一个帐户,并在单独的UPDATE中记入另一个帐户。这代表了汇款。如果借记成功但信用失败,您应该回滚整个交易,否则看起来钱就消失了。

因此,如果其中一个更改失败,则预期的用途是回滚事务。

您似乎在说,在您的应用程序中,如果其中一个更改失败,则可以。这让我觉得你已经不恰当地将变更分组到交易中。

确定哪些更改必须一起成功,并将这些更改放入一个事务中。任何不适用于此组的更改都应该在单独的事务中。

答案 2 :(得分:1)

你应该明确地使用ROLLBACK来清楚你要对以后必须阅读你的代码的人做些什么,实际上你可能是:)

此外,如果添加代码,即在COMMIT / ROLLBACK之后执行,最好明确触发它以获得更可预测的数据状态。如果您依赖自动ROLLBACK,那么该代码可能期望数据库处于未修改状态,而实际上它仍处于未通信的事务中。

答案 3 :(得分:1)

这取决于您一般如何进行错误处理。使用事务很好,因为如果事务中的代码抛出异常(可能是因为数据库查询失败也可能不是),通常你的异常处理程序会导致回滚。

此外,如果您在未提交的情况下关闭连接,例如因为进程意外退出,则回滚将隐式发生,这通常是一件好事(它提高了健壮性,因为当进程重新启动时,它可以再次尝试)< / p>

现在,当然,使用PHP和“旧的”mysql API不利于实现这一点,因为它不支持异常的错误报告。

但是,您可以通过注册PHP错误处理程序来解决此问题,该错误处理程序在发生错误时抛出异常,而不是执行默认的“充电进入灾难”方法:

"Captain, we've hit an iceberg
"Full steam ahead, put more coal in, we'll get to new york soon...

答案 4 :(得分:1)

如果您已将PHP配置为使用持久性MySQL连接,那么如果某些内容失败,则不回滚事务将导致后续连接出现问题。当脚本中止/退出时,事务不会自动中止,因为连接在后台保持活动状态。随后对此特定连接的任何后续重用将继续进行,就像没有发生任何事情一样,并且您最终处于此旧事务的中间。

同样,如果事务获取了任何锁,这些锁仍然保持活动状态,直到某些事情导致回滚或终止连接(自动回滚)。如果他们触摸锁定的表/行,您可能最终导致任何其他查询的日志堵塞。