• User Attivo

    begin, commit, rollback --> errori mysql su foreign key

    Ciao a tutti,
    la premessa è che son un po' confusa.
    Db mysql, con tabelle InnoDb, tra le altre due tabelle:
    -tabella "Padre" [id, etc...]
    -tabella "figlia"['id', 'lingua', ...]
    la figlia ha una chiave esterna su id, con l'id della tabella padre (on delete cascade).
    Utilizzandola da mysql funziona come mi aspetto:

    • se cerco di creare una tupla sulla figlia, il cui id non esiste nella tabella padre, mi lancia un errore
    • se elimino una tupla dalla tabella padre, elimina tutte le tuple della tabella figlia con quell'id.

    Fin qui tutto ok. Al db attacco un'interfaccia php/javascrip con le solite azioni: aggiungi, modifica, cancella.
    Tutto ok, fino al momento in cui incastro le query nelle "transazioni" (è corretto chiamarle così??) che il php mi dà su mysql:

    
    function begin() { @mysql_query("BEGIN"); } 
    function commit() { @mysql_query("COMMIT"); } 
    function rollback() { @mysql_query("ROLLBACK"); }  
    
    

    Per le quali, teoricamente, se la query va a buon fine fa il commit, diversamente fa il rollback, e riporta al db allo stato precedente della query.
    La funzioncina che mi gestisce questa operazione è banalissima:

    function doQuery($query){
        begin(); 
        $controll=mysql_query($query);
        if(!$controll){
             echo'Errore : '.mysql_error(); 
            rollback(); 
            return($controll);
            exit(); 
        } 
        commit(); 
        return($controll);
    }
    

    Ok, posto che con senza le transazioni, funziona tutto... utilizzando begin, commit e rollback php mi lancia un errore sulle insert nella tabella padre (!?!?!) facendo riferimento ad una foreign key sulla figlia (nella mia testa dovrebbe funzionare esattamente al contrario)
    La cosa divertente, è che sul db l'inserimento lo fa, ergo deduco che non faccia rollback.

    Ergo direi che sono parecchio confusa. La via più semplice è quella di abbandonare le transazioni, ma non mi sembra saggio: in quale altro modo posso garantire che se due utenti stanno lavorando contemporaneamente su una risorsa, non si "facciano le scarpe" vicendevolmente?

    Oppure sto commettendo un errore banalissimo che non vedo?

    Grazie fin da ora per chi ci perderà del tempo,

    mery


  • User Attivo

    Ok, vado in punizione dietro la lavagna per un'oretta!
    Commettevo un errorino madornale, lo riporto per dovere di cronaca nel caso qualcuno si trovi nella stessa situazione.
    Funzionavano sia le foreing key, sia le transazioni... semplicemente
    utilizzavo $id= mysql_insert_id();, fuori dalla transazione...ritornava zero, non l'id corretto!Per cui la query successiva (che popolava la tabella figlia), cercava di fare un'insert con id zero... motivo per il quale le foreign key mi davano un errore!

    Piccola modifica a doQuery:

    
    function doQuery($query){
        $data=array();
        begin(); 
        $data['controll']=mysql_query($query);
        $data['id'] = mysql_insert_id();
        if(!$data['controll']){
             echo'Errore : '.mysql_error(); 
            rollback(); 
            return($data);
            exit(); 
        } 
        commit(); 
        return($data);
    }