我有多个类方法,如果抛出异常,每个方法都使用事务和回滚。以下基本示例。
class TaskMapper
{
private $dblayer;
public function __construct(PDO $dblayer)
{
$this->dblayer = $dblayer;
}
public function save(Task $task)
{
try {
$this->dblayer->beginTransaction();
$stmt = ... // query/queries here
$stmt->execute();
$stmt2 = ... // query/queries here
$stmt2->execute();
$this->dblayer->commit();
} catch (\PDOException $e) {
$this->dblayer->rollBack();
// deal with exception here
}
}
public function editField($id, $field, $value)
{
try {
$this->dblayer->beginTransaction();
$stmt = ... // query/queries here
$stmt->execute();
$stmt2 = ... // query/queries here
$stmt2->execute();
$stmt->execute();
$this->dblayer->commit();
} catch (\PDOException $e) {
$this->dblayer->rollBack();
// deal with exception here
}
}
}
现在,我正在编写一个cron作业的脚本,该脚本使用包含类似于上述代码的多个类方法 - 包括事务和回滚以及异常。
例如:
if (date('j') == '1') {
// reset monthly count column
$task->editField(17, 'monthly_count', '0');
}
$task->save($task);
这是一个非常剥离的示例,但我想知道是否可以在try / catch块中的单个事务中包装所有方法调用,并在catch中回滚?所以将上面的代码包装在try / catch中,并在catch中使用事务和回滚?
如果没有,那么接近这种情况的最佳方法是什么,如果一个方法调用失败,其他方法必须回滚。
提前致谢。
答案 0 :(得分:1)
我宁愿添加一个答案,因为评论太短,无法解释。
基本上,您有两种方法可以在应用程序的单个事务中包含多个操作。
调用启动事务的方法。每个后续方法调用,属性更改都会导致数据库发生更改。这些操作期间的任何错误都将导致回滚。最后,您调用另一个提交整个事务的方法。
每个方法调用,属性更改只更改php对象状态,因此数据库不会更改。在对所有更改感到满意后,您将调用一个方法,该方法将所有更改持续存储到数据库中。此调用中也会执行回滚/提交。
Mysql不支持嵌套事务,因此要么将第一个方法与PDO:inTransaction结合使用,因为@YourCommonSense也是在调用editField()之前启动事务建议的,或者你必须取出数据库修改代码来自editField()和类似的调用,只使用save()。
答案 1 :(得分:0)
我自己从未使用它,但有一个PDO::inTransaction
方法,您可以使用它来查看是否启动了更高级别的事务。
所以你可以改为
if ( !$this->dblayer->inTransaction() ) {
$this->dblayer->beginTransaction();
}
也适用于提交。
将让您决定是否必须使用“本地”事务,从而可以使用“全局”事务将所有这些方法包装在一起。