Transações PHP, MySQL, DOP - O fetchAll () vem antes do commit ()?

Mais perguntas sobre transações!

O que tenho agora é uma bagunça de consultas agrupadas, que são todas revertidas manualmente, se houver alguma falha:

Bloco de código 1

$stmt1 = $db->prepare(...); // Update table1, set col=col+1
if($stmt1 = $db->execute(...)){

    $stmt2 = $db->prepare(...); // Insert into table2, id=12345
    if($stmt2 = $db->execute(...)){

        $stmt3 = $db->prepare(...); // Select val from table3
        if($stmt3 = $db->execute(...)){

            $result = $stmt3->fetchAll();
            if($result[0]['val'] == something){

                $stmt4 = $db->prepare(...); // Update table4, set status=2
                if($stmt4 = $db->execute(...)){

                    return true;

                }else{
                    $stmt1 = $db->prepare(...); // Update table1, set col=col-1 (opposite of above)
                    $stmt1 = $db->execute(...);

                    $stmt2 = $db->prepare(...); // Delete from table2, where id=12345 (opposite of above)
                    $stmt2 = $db->execute(...);

                    return false;
                }
            }

            return true;
        }else{
            $stmt1 = $db->prepare(...); // Update table1, set col=col-1 (opposite of above)
            $stmt1 = $db->execute(...);

            $stmt2 = $db->prepare(...); // Delete from table2, where id=12345 (opposite of above)
            $stmt2 = $db->execute(...);

            return false;
        }
    }else{
        $stmt1 = $db->prepare(...); // Update table1, set col=col-1 (opposite of above)
        $stmt1 = $db->execute(...);

        return false;
    }
}

É uma bagunça, difícil de depurar, difícil de adicionar, difícil de entender quando as consultas são grandes e não retornará todas as tabelas ao estado original se a conexão for perdida no meio.

Esse mesmo processo é ainda pior ao excluir uma linha, porque tudo nela precisa ser armazenado - apenas no caso de a operação precisar ser desfeita.

Agora eu seia maioria disso ainda funcionará quando eu a portar para uma única transação, mas a única parte da qual não tenho certeza é:

Bloco de código 2

$result = $stmt3->fetchAll();
if($result[0]['val'] == something){
    ... continue ...
}else{
    ... reverse operations ...
    return false;
}

Como a coleta de resultados seria realizada antes docommit() na transação. Do seguinte modo:

Bloco de código 3

$db->beginTransaction();    

try{
    $stmt1 = $db->prepare(...);
    $stmt1->execute();

    $stmt2 = $db->prepare(...);
    $stmt2->execute();

    $stmt3 = $db->prepare(...);
    $stmt3->execute();

    $result = $stmt3->fetchAll();
    if($result[0]['val'] == something){
        $stmt4 = $db->prepare(...);
        $stmt4->execute();
    }else{
        $db->rollBack();
        return false;
    }

    $db->commit();

    return true;
}catch(Exception $e){
    $db->rollBack();
    throw $e;
    return false;
}

Isso vai funcionar? Especificamente, posso incluir o$result = $stmt3->fetchAll(); antes acommit()e, em seguida, execute a consulta condicional?

Além disso, não tenho muita certeza disso, mas preciso do$db->rollBack(); dentro dotry bloco, se o código for encerrado (return false) antes de ocommit()?

questionAnswers(1)

yourAnswerToTheQuestion