Transaction php

Emanuele85

Utente Attivo
30 Gen 2021
118
0
16
Buonasera a tutti, il mio mini progetto va avanti e php mi appassiona sempre più, ma di tanto in tanto mi blocco per cavolate, e credo che questa volta sia una di quelle. In poche parole, ho la necessità di inserire dei dati su più tabelle Mysql, e tutto funziona perfettamente.
Ad un certo punto però mi è venuto il dubbio, ma se una delle 2 o più transazioni non va a buon fine, potrei trovarmi un Db "sporco" e sinceramente vorrei evitarlo, ma tutto ciò, vorrei farlo soprattutto per imparare (dato che il db sarebbe mio e pulito o sporco poco importa). Vi posto un po di codice per farvi capire cosa ho fatto:
PHP:
try {
      
 $dbh->beginTransaction();
 
 $sql="insert into allegati(id_pratica,rif_pratica,descrizione_all,nome_file,time_upload,creato_da,visibile)values(:id_pratica,:rif_pratica,:descrizione_all,:nome_file,:time_upload,:creato_da,:visibile)";

$query=$dbh->prepare($sql);
    
$query->bindParam(':id_pratica',$id,PDO::PARAM_STR);
$query->bindParam(':rif_pratica',$_POST['rif_pratica'],PDO::PARAM_STR);
$query->bindParam(':descrizione_all',$_POST['nome_allegato'],PDO::PARAM_STR);
$query->bindParam(':nome_file',$userfile_name,PDO::PARAM_STR);
$query->bindParam(':time_upload',$time_upload,PDO::PARAM_STR);
$query->bindParam(':creato_da',$creato_da,PDO::PARAM_STR);
$query->bindParam(':visibile',$visibile,PDO::PARAM_STR);
 
$sql2="insert into movimenti( id_pratica, cod_utente_movimento,creato_il, codcol_pratica, tipo_movimento)values(:id_pratica,:creato_da,:time_upload,:codcol_pratica,:tipo_movimento)";
 
$query2=$dbh->prepare($sql2);

$query2->bindParam(':id_pratica',$id,PDO::PARAM_STR);
$query2->bindParam(':creato_da',$creato_da,PDO::PARAM_STR);
$query2->bindParam(':time_upload',$time_upload,PDO::PARAM_STR);
$query2->bindParam(':codcol_pratica',$codice_coll,PDO::PARAM_STR);
$query2->bindParam(':tipo_movimento',$tipo_movimento,PDO::PARAM_STR);

$query->execute();
$query2->execute();

 $dbh->commit();
 
 if (is_dir($root_principale)) {
  // Se la cartella esiste ci copio il File
 
  move_uploaded_file($nome_file_tmp, $root_principale . $userfile_name);
  echo '<script>alert("Allegato Salvato con Successo")</script>';
 
}else{
    
  mkdir($root_principale);
 
     move_uploaded_file($nome_file_tmp, $root_principale . $userfile_name);
    
    echo '<script>alert("Allegato Salvato con Successo")</script>';
}

        } catch (Exception $e) {
            echo $e-> getMessage();
            $dbh->rollback();
            throw $e;
        }
    }

Praticamente l'insert funziona, ma se cambio per esempio il nome ad un campo della query2 non accade nulla...cioè esegue la query 1 e non esegue la query2 senza darmi alcuna anomalia. Il Db è Mysql, e dovrebbe avere in automatico l'autocommit ma non si dovrebbe interrompere con beginTransaction? in sostanza le query vengono eseguite con l'execute fregandosene di tutto il resto...

Grazie a tutti per la pazienza
E
 
Ciao emanuele penso che ti manchi la gestione degli errori prova qualcosa come questo per entrambi le query ti posto il codice solo per la prima query ma è uguale anche per la seconda...fammi sapere se vedi quello che vorresti ciao.
Codice:
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
try
{
$query=$dbh->prepare($sql);
    
$query->bindParam(':id_pratica',$id,PDO::PARAM_STR);
$query->bindParam(':rif_pratica',$_POST['rif_pratica'],PDO::PARAM_STR);
$query->bindParam(':descrizione_all',$_POST['nome_allegato'],PDO::PARAM_STR);
$query->bindParam(':nome_file',$userfile_name,PDO::PARAM_STR);
$query->bindParam(':time_upload',$time_upload,PDO::PARAM_STR);
$query->bindParam(':creato_da',$creato_da,PDO::PARAM_STR);
$query->bindParam(':visibile',$visibile,PDO::PARAM_STR);
$query->execute();
}
catch(PDOException $e)
{
    $message = $e->getMessage();
    return $message;
}
 
Grazie Illiterate... A breve ti farò sapere,purtroppo solo a tarda sera ho modo di fare questi esperimenti. Comunque il tuo esempio mi sembra uguale al mio,sbaglio? Gli attributi errormode ecc gli ho messi solo che non gli ho incollati nel codice che ho inviato. Hai un return nel catch che io non ho usato... Comunque proverò tra poco...intanto grazie milleeee
 
Illiterate ho appena provato il tuo suggerimento, in sostanza ho tolto il setAttribute dal file di connessione e l'ho messo direttamente sul file che gestisce le transazioni e qualcosa è cambiato...nel senso che... la parte della transaction sembra funzionare perfettamente ma non ricevo errori ,resto con una pagina bianca. Farò altri test e ti aggiornerò ma al momento è così...

Grazie Ancora...
E
 
Ciao togli return e fai un echo dell'errore poi da notare che è un PDoexception
Codice:
catch(PDOException $e)
{
    $message = $e->getMessage();
    echo $message;
}
Dimmi se risolvi cosi...
 
Perfetto... ma, giusto per capire, l'errore stava nel fatto che non avevo il setAttribute nello stesso file delle insert? perchè, oltre al fatto di non ricevere errori ieri, mi eseguiva una query si e una query no, ignorando il fatto che stessi usando le transaction
 
Ciao senza vedere tutto il codice e la struttura dei tuoi file non so dare una risposta precisa ma nel codice che hai postato mancava certamente la riga
Codice:
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
inoltre l'eccezione che usavi era un eccezione generica.
Quindi risolto?
 
come controprova puoi rimettere
Codice:
catch(Exception $e)
{
    $message = $e->getMessage();
    echo $message;
}
e vedi se ti da l'errore o no
 
prego, mettendo l'eccezione generica
Codice:
catch(Exception $e)
{
    $message = $e->getMessage();
    echo $message;
}
te lo mostra l'errore?
 
Buonasera a tutti...illitteral ti confermo che con errore generico non mi tira fuori nulla...avevi ragione...

Grazie mille mi hai risolto molti problemi...
A presto
E
 

Discussioni simili