我有一个执行mysql查询的方法deleteUser(..)并调用另一个调用另一个mysql查询的方法logAction(..)。
在这些方法中处理事务的最佳方法是什么?
伪代码示例:
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'两次。方法logAction()调用' COMMIT'在deleteUser()完成之前过早。
有没有办法管理这种嵌套方法中的事务?
答案 0 :(得分: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更高层次化,或者将查询放低。
P.S。您可以使用autocommit变量来检查正在启动的事务。