Транзакции PHP, MySQL, PDO - Может ли fetchAll () прийти перед commit ()?
Больше вопросов по сделке!
То, что у меня есть сейчас, - это беспорядок связанных запросов, которые все вручную меняются, если таковые возникают:
Блок кода 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;
}
}
Это беспорядок, его трудно отладить, трудно добавить, трудно понять, когда запросы велики, и он не вернет все таблицы в исходное состояние, если соединение потеряно на полпути.
Этот же процесс еще хуже при удалении строки, потому что все в ней должно быть сохранено - на случай, если операция должна быть отменена.
Теперь я знаюсамый это все еще будет работать, когда я перенесу его на одну транзакцию, но одна часть, в которой я не уверен:
Блок кода 2
$result = $stmt3->fetchAll();
if($result[0]['val'] == something){
... continue ...
}else{
... reverse operations ...
return false;
}
Поскольку сбор результатов будет проводиться доcommit()
в сделке. Следующее:
Блок кода 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;
}
Будет ли это работать? В частности, могу ли я включить$result = $stmt3->fetchAll();
до commit()
, а затем выполнить условный запрос?
Кроме того, я не совсем уверен в этом, но мне нужно$db->rollBack();
в пределахtry
заблокировать, если код завершен (return false
) передcommit()
?