Laravel rollback transaction non funziona

di Anonimizzato26866 il
11 risposte
Ciao,
ho un problema nel gestire la rollback in caso di eccezione.
Dopo la prima insert, lancio un'eccezione.
L'eccezione viene catturata, infatti la trovo sul log, ma non esegue la rollback, infatti mi trovo il record inserito sul DB.
Qualcuno sa cosa può essere?
Grazie mille

  function test(Request $req)
    {
        DB::beginTransaction();
        try
        {
            .....................
            DB::table('mytable1')->insert( ... );
			
			if(true){
              throw new Exception('error');
            }
			
			DB::table('mytable2')->insert( ... );
			.....................
            DB::commit();         
            
        }catch (\Exception $e) {
			Log::channel('mioLog')->info($e);
            DB::rollBack();
        }finally {
            //DB::disconnect('mysql');
        }
        
    }

11 Risposte

  • folletto_folle ha scritto:


    L'eccezione viene catturata, infatti la trovo sul log, ma non esegue la rollback, infatti mi trovo il record inserito sul DB.
    Ciao, le funzioni sono case sensitive
    DB::rollBack() deve diventare DB::rollback()

    Bye
  • Ciao Salvo,
    grazie per la risposta.
    Anche con rollback non funziona (cmq rollBack me lo indicava come suggerimento l'editor).
    Ma bisogna cambiare qualche impostazione in qualche file di configurazione che tu sappia?
  • Di sicuro devi aver impostato
    use Illuminate\Support\Facades\DB;
    Se l'editor ti suggerisce rollBack va bene pure, potrebbe essere questione di versioni utilizzate.

    Trovi una guida utile qui

    Io personalmente mi trovo molto bene con il metodo DB::transaction a cui passi il parametro di quante volte tentare l'esecuzione prima di andare in errore e poi esegue automaticamente il rollback/commit.
  • Si si ho importato il package use Illuminate\Support\Facades\DB;
    Ma infatti non va in errore , l'unica cosa che non mi fa la rollback -_-
    Ho ancora provato a mettere tutto dentro DB::transaction(function () { ma niente di niente ....booo
  • Allora il problema è da ricercare nel server mysql.
    La tabella l'hai creata tramite artisan oppure manualmente?
    Fai una prova manualmente ad inserire una query e fare il rollback
    
    SET autocommit=0;
    START TRANSACTION; 
    ..La tua query...
    ROLLBACK;
    
  • Ciao Tatino,
    manualmente funziona.
    Comunque le tabelle le ho generate manualmente.
    Ho pure attivato il debug di laravel e ho notato che nel tab Queries leggo il beginTransaction, le select, le insert, la commit ma non la rollback -_-
  • Laravel usa PDO mentre phpmyadmin mysqli.
    Puoi provare manualmente PDO direttamente nel codice PHP (senza laravel) ? https://www.php.net/manual/en/pdo.rollback.ph
    Alcuni database, incluso MySQL, emettono automaticamente un COMMIT implicito quando un'istruzione DDL (database Definition Language) come DROP TABLE o CREATE TABLE viene emessa all'interno di una transazione. Il COMMIT implicito ti impedirà di ripristinare qualsiasi altra modifica all'interno del limite della transazione.
  • Ma quindi per gestire il rollback con Laravel, non devo creare le tabelle manualmente?
  • Prova il codice php puro precedente, se non esegue il rollback leggi https://dev.mysql.com/doc/refman/8.0/en/implicit-commit.html mi sembra che indica autocommit a 1 se già non è 1, quindi dopo farai una select per verificare se autocommit è 1 lo imposti a 0... fai svariati tentativi. In realtà si dovrà considerare anche con START TRANSACTION, autocommit rimane disabilitato fino a quando non si termina la transazione con COMMIT o ROLLBACK. La modalità autocommit torna quindi allo stato precedente.

    Poi magari si tenta di far girare il codice anche su laravel e chiedi modifica a loro.
  • Ho provato con la transaction manuale e sembra funzionare bene .
    Comunque ho notato una cosa strana usando la transaction di Laravel.
    Se faccio la 1 insert e dopo lancio un'eccezione, la rollback non funziona e mi trovo il record della prima insert sul DB.
    Se invece faccio la 1 insert e nella seconda insert metto per esempio un nome di una tabella che non esiste, sembra che la rollback venga eseguita (infatti non mi trovo il record inserito).
    Booo comunque grazie mille del supporto
  • Transizione manuale tramite file php, non in phpmyadmin? Ti occorre tramite php indipendentemente dal problema su laravel, cioè codice php puro senza altre interpretazioni, con funzioni native in php https://www.iprogrammatori.it/forum-programmazione/post8673408.html#p8673408
    Ad esempio se la prima insert esiste mentre la seconda insert no, che cosa fa php? E se fai viceversa? [Code]<?php try { $dbh = new \PDO('mysql:host=localhost;dbname=nome', 'user', 'pass', array(PDO::ATTR_PERSISTENT => true)); echo "Connected\n"; } catch (\Exception $e) { die("Unable to connect: " . $e->getMessage()); } try { $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $dbh->beginTransaction(); $dbh->exec("insert into staff (id, first, last) values (23, 'Joe', 'Bloggs')"); $dbh->exec("insert into salarychange (id, amount, changedate) values (23, 50000, NOW())"); $dbh->commit(); } catch (\Exception $e) { $dbh->rollBack(); echo "Failed: " . $e->getMessage(); } ?> Transizione e autocommit in PDO, fondamentali https://www.php.net/manual/en/pdo.transactions.ph
Devi accedere o registrarti per scrivere nel forum
11 risposte