如何在 PHP 中管理嵌套的数据库事务?
Posted
技术标签:
【中文标题】如何在 PHP 中管理嵌套的数据库事务?【英文标题】:How to manage nested database transactions in PHP? 【发布时间】:2014-11-27 14:56:41 【问题描述】:我有一个方法 deleteUser(..) 执行一个 mysql 查询并调用另一个方法 logAction(..) 调用另一个 mysql 查询。
在这些方法中处理事务的最佳方式是什么?
示例伪代码:
function deleteUser($userId)
$db->execute('BEGIN TRANSACTION');
$userCount = $db->execute("DELETE FROM users WHERE id=$userId");
logAction('USER DELETED');
$db->execute('INSERT INTO ... another action');
$db->execute('COMMIT');
function logAction($action)
$db->execute('BEGIN TRANSACTION');
$db->execute('INSERT INTO logtable ... ACTION');
if (error)
$db->execute('ROLLBACK');
$db->execute('COMMIT');
如您所见,我从 deleteUser() 方法调用 logAction,并遇到了两次“BEGIN TRANSACTION”。在 deleteUser() 完成之前,方法 logAction() 过早地调用了“COMMIT”。
有没有办法在这种嵌套方法中管理事务?
【问题讨论】:
【参考方案1】:MySql 不支持嵌套事务。还有
开始一个事务会导致提交任何待处理的事务
http://dev.mysql.com/doc/refman/5.5/en/commit.html
但是您需要在一个事务中执行这些查询或单独执行它们。你坚持在事务中运行你的方法。
function deleteUser($userId)
if ($this->notInTransation()) throw new NotInTransactionException('not in transaction');
$userCount = $db->execute("DELETE FROM users WHERE id=$userId");
logAction('USER DELETED');
$db->execute('INSERT INTO ... another action');
function logAction($action)
if ($this->notInTransation()) throw new NotInTransactionException('not in transaction');
$db->execute('INSERT INTO logtable ... ACTION');
这样可以确保您的查询在一个事务中运行。使用这种方法,您应该将 begin、rollback、commit 放在更高的层次结构中,或者将查询放在更低的位置。
附:您可以使用autocommit 变量来检查正在启动的事务。
【讨论】:
以上是关于如何在 PHP 中管理嵌套的数据库事务?的主要内容,如果未能解决你的问题,请参考以下文章