MySQL如何正确使用事务?

时间:2019-01-31 08:29:50

标签: mysql transactions

我在项目中遇到实施交易的需求-这是我以前从未做过的事情。我已经检查过我的aytocommit设置为1-我不确定是否需要触摸它?

现在,我有一组脚本,所有脚本都包含首先连接到数据库的函数。有一个放置mysqli_begin_transaction($link);mysqli_autocommit($link, FALSE);的理想场所,因此无论特定脚本是否需要它,我都会无处不在进行事务处理,然后关闭自动提交功能-php.net上的文档那里很差,但是我应该这样做。所以我的问题不。 1&2将是:是否可以在任何地方启动事务,而不管脚本是否需要它?我也应该像这样禁用自动提交吗?

现在让我们说,我有这样的脚本(很抱歉没有提供实际的代码,但是我的问题是关于事务的工作方式,而不是代码本身):

~insert and/or update things
~do something aka "line 2"
~insert and/or update things again 

似乎就像本书中的例子。我显然希望所有插入和更新,或者什么都不会发生。因为我已经开始事务,所以我假设没有任何东西提交,除非我调用mysqli_commit ($link);。但是这里有一个小问题:我在脚本的末尾没有添加任何“页脚”,现在这样做似乎是一场噩梦,因此我没有任何地方可以提交。所以问题不。 3是:即使我将autocommit设置为false,脚本结束(或调用exit;die();之后,查询也会自动提交吗?还是我需要致电提交/不关闭自动提交?

现在是时候解决某些失败的情况了,我需要回滚。与上述相同-我需要调用mysqli_rollback (mysqli $link);,还是纯粹不调用commit就足够了?我在这里指的是脚本无法正常结束的情况。诸如在“第2行”上工作时关闭服务器电源之类的情况,或者由于花费大量时间(set_time_limit使其停止)而被停止。

1 个答案:

答案 0 :(得分:1)

这是一个有点笼统的问题,因此,我将尽我所能涵盖所有内容。

首先,您可以忽略mysqli api(特定于api的事务功能只是包装器),而直接进入MySQL manual。这里重要的是禁用自动提交和启动事务是同一回事。同样,单个查询(包括通过触发器进行的修改)始终是事务。

您对问题1和2的回答是“可能不是”。这在很大程度上取决于现有代码对数据库连接的假设,以及应用程序的结构。

根据您在问题中提到的内容,答案将是:仅将交易放在需要交易的地方会更好。

对于问题3:它将不会自动提交。不过,您可以使用register_shutdown_function来做到这一点,尽管我不建议这样做。

有些语句(implicit commits)将自动提交事务。这些包括所有DDL语句(CREATE,ALTER ...)以及TRUCNATE,LOCK TABLES等。这基本上意味着这些语句不能在事务中使用。

当连接终止时,MySQL将回滚事务。

我建议仅将事务添加到需要它们的代码中(为了安全起见,您可以对对数据库执行多个写查询的所有代码执行此操作)。

经典方法是:

START TRANSACTION
query
other things
another query
some other stuff
3-rd query
...
COMMIT

这里的主要目的是确保仅在未发生错误的情况下才提交。

将回滚保留到任一连接终止(如果使用持久连接,则退回至register_shutdown_function),因为要确保每个脚本都具有正确运行的回滚逻辑是很困难的:)

这将确保如果发生坏事(异常,致命错误,时间/内存限制,断电,流星...),则什么也不做。

也可以在功能/方法级别(嵌套和类似堆栈)进行事务处理,但这超出了此问题的范围。