回答问题

我有两个复杂的 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()无需修改即可工作。

Logo

华为、百度、京东云现已入驻,来创建你的专属开发者社区吧!

更多推荐