PHP PDO 对象如何判断它是否已经在 MySQL 事务中?
回答问题 我有两个复杂的 PHP 对象,每个对象都有几个 MySQL 表中的数据。 有时,我只需要从数据库中删除一个对象 A,这需要 3 个 SQL 语句。 有时,我需要从数据库中删除一个对象 B,这需要 4 个 SQL 语句,并且还需要查找并删除对象 B 拥有的所有对象 A。 所以在函数 delete_A() 中,我在事务中执行这些语句。在 delete_B() 函数内部,我想运行一个涵盖 de
·
回答问题
我有两个复杂的 PHP 对象,每个对象都有几个 MySQL 表中的数据。
有时,我只需要从数据库中删除一个对象 A,这需要 3 个 SQL 语句。
有时,我需要从数据库中删除一个对象 B,这需要 4 个 SQL 语句,并且还需要查找并删除对象 B 拥有的所有对象 A。
所以在函数 delete_A() 中,我在事务中执行这些语句。在 delete_B() 函数内部,我想运行一个涵盖 delete_A() 内部活动的大事务。如果删除 B 的整个原子失败了,我需要在回滚中恢复它的所有 A。
如何更新 delete_A() 的定义以仅打开一个新事务如果没有更大的事务正在运行。
我希望能够做这样的事情,但autocommit
属性似乎没有被beginTransaction()
改变
function delete_A($a){
global $pdo;
$already_in_transaction = !$pdo->getAttribute(PDO::ATTR_AUTOCOMMIT);
if(!$already_in_transaction){
$pdo->beginTransaction();
}
//Delete the A
if(!$already_in_transaction){
$pdo->commit();
}
}
function delete_B($b){
global $pdo;
$pdo->beginTransaction();
foreach($list_of_As as $a){
delete_A($a);
}
$pdo->commit();
}
Answers
我最终只是使用->beginTransaction()
抛出的异常来确定我是否在事务中,并使用它来决定是否在内部循环中提交。所以delete_A()
最终看起来像:
function delete_A($a){
global $pdo;
try {
$pdo->beginTransaction();
} catch (PDOException $e) {
$already_in_transaction = true;
}
//Delete the A
if(!$already_in_transaction){
$pdo->commit();
}
}
并且delete_B()
无需修改即可工作。
更多推荐
已为社区贡献23584条内容
所有评论(0)