我有两个复杂的
PHP对象,每个对象都有几个MysqL表中的数据.
有时,我只需要从数据库中删除一个对象A,这需要3个sql语句.
有时,我需要从数据库中删除一个对象B,这需要4个sql语句,并且还需要查找和删除对象B拥有的所有对象A.
所以在函数delete_A()中,我在一个事务中执行那些语句.在delete_B()函数内部,我想运行一个覆盖delete_A()内部活动的大型事务.如果删除B的整个原子都失败了,我需要在回滚中恢复它的所有A.
如果尚未运行更大的事务,如何更新delete_A()的定义以仅打开新事务.
我希望能够做这样的事情,但autTraommit属性似乎没有被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(); }
PDO :: ATTR_AUTOCOMMIT不是指示符属性,它是一个控件属性.它控制sql语句在完成时是否隐式提交.
您可以调用PDO :: inTransaction(),如果您没有正在进行的事务,则返回0;如果您有未完成的事务需要提交或回滚,则返回1.但是,此功能没有记录,因此很难说它是否可以安全地依赖它存在于所有未来版本的PDO中.
我建议PHP开发人员不要尝试管理函数或类范围内的事务.您应该在应用程序的顶层管理事务.
也可以看看:
> How do detect that transaction has already been started?
> Multiple Service Layers and Database Transactions