You only need separate PDO exception handlers if you want to handle exceptions thrown by the different inserts differently. Stick with the second sample you posted, possibly adding an if around the $ins1->execute()
Edit: from taking a closer look at the source, the only times the MySQL driver will return False involve mistakes in the prepared statement parameters, which you're not using. You should be fine with:
PHP Code:
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
...
try {
$dbh->beginTransaction();
// $query will hold the most recent query, in case of failure.
$query =$ins1;
$ins1->execute();
$query =$ins2;
$ins2->execute(); // insert on second table
$dbh->commit(); // inserts validated
echo 'That is OK';
} catch(PDOException $err); { // case of error
// $query refers to the failed query
$dbh->rollback(); // inserts not validated
ob_start();
$query->debugDumpParams();
$msg = $err . "\n\nquery: " . ob_get_contents();
ob_end_clean();
echo '<p>There is an internal problem.';
if (user is admin) {
echo '</p><pre>', $msg, '</pre>';
} else {
error_log($msg);
error_log($msg, 1, $adminEmail);
echo 'It's been logged, and we'll look into it.</p>';
}
}
If you find yourself needing to pass parameters to execute, then you might need return value checks for code maintenance.