Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 13

Discussione: Uso di rollback()

  1. #1
    Utente di HTML.it
    Registrato dal
    Dec 2007
    Messaggi
    17

    Uso di rollback()

    Salve a tutti,
    Ho già formulato questa domanda ma in modo probabilmente impreciso e non ho avuto risposte. Provo a riformularla meglio.

    L'interfaccia java.sql.Connection permette di eseguire più comandi sql in modo transazionale tramite il metodo setAutoCommit(boolean ac) impostando ac = false.

    In effetti se in un blocco try-catch (obbigatorio per gestire l'eccezione sql) si eseguono più comandi sql e di seguito si esegue la rollback() ( ad esempio perchè una delle query ha interessato un numero di righe inaspettato) il risultato è, giustamente, l'annullamento di tutti i comandi eseguiti.
    Il problema è che se uno dei comandi lancia un'eccezione sql (ad es. perchè una insert ritorna una chiave duplicata) e quindi si abbandona il blocca try per andare nel blocco catch, anche se qui si esegue la rollback() l'effetto voluto non c'è perchè i dati dei comandi sql precedenti a quello in errore si ritrovano in BD.
    Ho verificato questo con due database: MySql e DB2; il comportamento è lo stesso.

    Qualcuno ne sa qualcosa?

    Grazie

  2. #2
    Per MySql posso dirti che l'inconsistenza si verifica in base all'engine usato per le tabelle. Di default, Mysql usa l'engine MyISAM che non supporta le transazioni.

    Devi modificare l'engine della tabella, utilizzando ad esempio INNODB, che supporta le transazioni.

    Saluti,
    Pasquale Congiusti'.

  3. #3
    Utente di HTML.it
    Registrato dal
    Dec 2007
    Messaggi
    17
    Mi scuso per non aver specificato meglio, ma le prove che ho fatto con MySql sono state fatte con tabelle INNODB. Con MYISAM non funzionerebbe neppure mettendo la rollback() di seguito ai comandi nel blocco try (prove eseguite da me).
    Ti ringrazio comunque e ti sarei grato se tu volessi fare delle prove e, nel caso ti succeda come a me, cercare una soluzione perchè il problema non è dipoco conto.

  4. #4
    Con la mia configurazione tutto funziona regolarmente.
    Facendo questo test:

    connection.setAutoCommit(false);
    //Effettuo la query
    try{
    for (int i=1;i<=5;i++){
    String sql=null;
    //facciamo fallire l'ultimo inserimento con una query sbagliata
    /*if (i==5){
    sql="Insert";
    }else*/
    sql="INSERT INTO resource (title, description) values ('test"+i+"','success')";

    pst=connection.prepareStatement(sql);
    pst.execute();
    }
    //Commit
    connection.commit();
    }catch(Exception e){
    //Rollback
    connection.rollback();
    }

    Facendo fallire deliberatamente, il rollback funziona correttamente. Commentando l'errore l'inserimento va a buon fine.

    La mia configurazione e' MySQL 5 e dispari. Posta il codice che gli diamo un'occhiata.
    Saluti,
    Pasquale Congiustì.

  5. #5
    Utente di HTML.it
    Registrato dal
    Dec 2007
    Messaggi
    17
    Il codice è il seguente:

    try {
    conn.setAutoCommit(false);
    String insert = "insert into prove.table1 " +
    "(codice " +
    ", descrizione) " +
    "values (3,'prova' ) ";
    System.out.println("Insert " + insert);

    java.sql.PreparedStatement stmt = conn.prepareStatement(insert);
    stmt.execute(insert);


    insert = "insert into prove.table2 " +
    "(codice " +
    ", numero) " +
    "values (2,10 ) ";
    System.out.println("Insert " + insert);


    stmt = conn.prepareStatement(insert);
    stmt.execute(insert);
    stmt.close();
    conn.commit();
    }
    catch(java.sql.SQLException sqle)
    {
    System.out.println("Errore SQL: " + sqle.getMessage());
    System.out.println("codice errore: " + String.valueOf(sqle.getErrorCode()));
    try {
    conn.rollback();
    ConnectionUtil.rilasciaConnessionePool(conn);
    System.out.println("Rollback effettuata ");
    }catch(java.sql.SQLException qle) {
    System.out.println("Errore SQL rollback: " + sqle.getMessage());
    }
    }

    L'ambiente è un progetto WEB su eclipse; questa in particolare è una servlet di prova.
    Tutto è locale (AS e DB).

  6. #6
    Prova a chiudere lo statement (st.close()) dopo aver effettuato il commit().
    Saluti,
    Pasquale Congiustì.

  7. #7
    Utente di HTML.it
    Registrato dal
    Dec 2007
    Messaggi
    17
    Scusa, ancora una volta non mi sono spiegato bene:

    - a BD pulita le due insert vanno tranquillamente a buon fine
    - a questo punto vado in BD e tolgo la riga inserita con la prima insert
    - rieseguo; la prima insert va a buon fine, ma la seconda trova la chiave duplicata (la chiave è la colonna "codice" per ambedue le tabelle);
    - l'esecuzione procede nel blocco catch incontrando la rollback(). Peccato che andando in BD ritrovo la riga che avevo cancellato nella tabella 1 e che non dovrei trovare per effetto della rollback()

    A complicare il tutto ti dico che se a BD pulita metto una rollback() al posto della commit(), in BD non trovo niente ed è giusto che sia così. Il problema sembra essere che non appena si lascia il blocco try c'è una commit non voluta.

    Saluti e grazie ancora

  8. #8
    Prova ad usare due Statement distinti, potrebbe essere legato al fatto che appena lasci lo statement, vi sia un commit di tutte le richieste pendenti.
    Saluti,
    Pasquale Congiustì.

  9. #9
    No, non e' quello, scusa la risposta errata.
    Saluti,
    Pasquale Congiustì.

  10. #10
    Utente di HTML.it
    Registrato dal
    Dec 2007
    Messaggi
    17
    Figurati...con tutti gli errori che faccio io...
    La cosa che mi preoccupa è che a te funziona, quindi si tratta di qualche impostazione che di solito è difficie beccare.
    La cosa strana (o forse no) è che lo stesso problema me lo da anche su altre istallazioni come ad es. il portatile.
    La cosa ancora più strana è che lo stesso problema esatto e identico me lo da anche con altri DB. Quindi si tratta probabilmente di un problema legato all'ambiente di sviluppo o di runtime.
    Io uso eclipse con jre 5.0.11; l'application server è Geronimo 1.1 di Apache basato su Tomcat.
    Tu che cosa usi?

    Ciao
    Roberto

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.