Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 20
  1. #1
    Utente di HTML.it
    Registrato dal
    Mar 2009
    Messaggi
    174

    Commit manuale su MySQL da Java

    Ciao a tutti! devo gestire una transazione creata da due insert e nel caso in cui la prima insert va a buon fine e la seconda no voglio che lo stato del db torni a come era prima della insert n°1. Per far ciò dopo aver creato la connessione con DriverManager, imposto conn.setAutocommit(false), creo il savepoint con conn.setSavepoint e poi eseguo la prima query, faccio commit, faccio la seconda query, faccio commit, la seconda è fallita e qnd faccio il rollback ottengo un errore che mi dice che il savepoint non esiste. Ciò è dovuto al fatto che la prima commit mi ha giustamente eliminato il savepoint, allora come posso fare? Mi dareste una mano?! Grazie infinite.

  2. #2

    Re: Commit manuale su MySQL da Java

    Originariamente inviato da Hermiod
    Ciao a tutti! devo gestire una transazione creata da due insert e nel caso in cui la prima insert va a buon fine e la seconda no voglio che lo stato del db torni a come era prima della insert n°1. Per far ciò dopo aver creato la connessione con DriverManager, imposto conn.setAutocommit(false), creo il savepoint con conn.setSavepoint e poi eseguo la prima query, faccio commit, faccio la seconda query, faccio commit, la seconda è fallita e qnd faccio il rollback ottengo un errore che mi dice che il savepoint non esiste. Ciò è dovuto al fatto che la prima commit mi ha giustamente eliminato il savepoint, allora come posso fare? Mi dareste una mano?! Grazie infinite.
    scusa ma perche non esegui prima le 2 insert se nessuna delle due ti da errore fai il commit, altrimenti rollback
    http://www.anobii.com/isalreadyinuse

  3. #3
    Utente di HTML.it
    Registrato dal
    Mar 2009
    Messaggi
    174
    Grazie innanzi tutto per la risposta! Forse sbaglio a farlo, ma se faccio la prima insert e non dò il commit è come se la query non venisse mai eseguita. Infatti il problema nasce da li. Avevo già provato, ma appunto, forse sbaglio a farlo. Questo è il frammento di codice
    codice:
    Savepoint stato = null;
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String passwordCheck = request.getParameter("passwordcheck");
        if (!username.equals("") && !password.equals("") && !passwordCheck.equals("")) {
            if (isPasswordCorretta(password, passwordCheck)) {
                if (isUsernameUnico(username)) {
                    int id = getAccountId(username);
                    if (id == -1) {
                        Connection conn = null;
                        Statement stmt = null;
                        ResultSet rs = null;
                        try {
                            conn = DriverManager.getConnection(strConn, dbuser, dbpassword);
                            conn.setAutoCommit(false);
                            stato = conn.setSavepoint();
                            stmt = conn.createStatement();
                            String queryAccount = "INSERT INTO srt_accounts (username, password, tipo) VALUES ('"
                                + codificaApici(username) + "', '"
                                + md5(codificaApici(password)) + "', '"
                                + codificaApici(request.getParameter("tipo")) + "')";
                            
                            int rows = stmt.executeUpdate(queryAccount);
                            conn.commit();
                            if (rows > 0) {
                                String nome = request.getParameter("nome");
                                String cognome = request.getParameter("cognome");
    
                                char tipoUtente = request.getParameter("tipo").charAt(0);
                                switch (tipoUtente) {
                                    case 'a': {
                                            String email = request.getParameter("email");
                                            if (!nome.equals("") && !cognome.equals("") && !email.equals("")) {
                                                if (isEmailUnica("srt_amministratori", email)) {
                                                    id = getAccountId(username);
                                                    String queryUtente = "INSERT INTO srt_amministratori (idaccount, nome, cognome, email) VALUES ('"
                                                            + id + "', '"
                                                            + codificaApici(nome) + "', '"
                                                            + codificaApici(cognome) + "', '"
                                                            + codificaApici(email) + "')";
                                                    rows = stmt.executeUpdate(queryUtente);
                                                    if (rows > 0) {
                                                        conn.commit();
                                                    } else {
                                                        conn.rollback(stato);
                                                    }
                                                } else {
                                                    // email non valida
                                                    conn.rollback(stato);
                                                    response.sendRedirect("error.jsp?id=6");
                                                    return;
                                                }
                                            } else {
                                                // campi obbligatori
                                                conn.rollback(stato);
                                                response.sendRedirect("error.jsp?id=2");
                                                return;
                                            }
                                        }
                                        break;

  4. #4
    Utente di HTML.it
    Registrato dal
    Mar 2009
    Messaggi
    174
    Ecco cosa mi succede se metto una sola commit alla fine
    codice:
    com.mysql.jdbc.MysqlDataTruncation: Data truncation: Out of range value for column 'idaccount' at row 1
            at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2983)
            at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1631)
            at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1723)
            at com.mysql.jdbc.Connection.execSQL(Connection.java:3277)
            at com.mysql.jdbc.Statement.executeUpdate(Statement.java:1402)
            at com.mysql.jdbc.Statement.executeUpdate(Statement.java:1317)
            at org.apache.jsp.jsp.newinsertion_jsp._jspService(newinsertion_jsp.java:243)
            at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
            at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
            at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:377)
            at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
            at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
            at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
            at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
            at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
            at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
            at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
            at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
            at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
            at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
            at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
            at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
            at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
            at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
            at java.lang.Thread.run(Thread.java:619)

  5. #5
    Originariamente inviato da Hermiod
    Ecco cosa mi succede se metto una sola commit alla fine
    codice:
    com.mysql.jdbc.MysqlDataTruncation: Data truncation: Out of range value for column 'idaccount' at row 1
            at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2983)
            at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1631)
            at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1723)
            at com.mysql.jdbc.Connection.execSQL(Connection.java:3277)
            at com.mysql.jdbc.Statement.executeUpdate(Statement.java:1402)
            at com.mysql.jdbc.Statement.executeUpdate(Statement.java:1317)
            at org.apache.jsp.jsp.newinsertion_jsp._jspService(newinsertion_jsp.java:243)
            at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
            at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
            at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:377)
            at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
            at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
            at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
            at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
            at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
            at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
            at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
            at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
            at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
            at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
            at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
            at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
            at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
            at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
            at java.lang.Thread.run(Thread.java:619)
    ma questo errore dice che scrivi un valore piu lungo di quello possibile per il tipo di campo
    http://www.anobii.com/isalreadyinuse

  6. #6
    Dovresti evitare di usare il savepoint. Come ti sei accorto tu stesso, dopo il commit il savepoint è giustamente inutilizzabile in quanto sei entrato in una transazione diversa.
    Quindi, togli il savepoint, evita di fare commit ed esegui tutti gli statement necessari nella tua transazione. Se tutto è ok solo alla fine esegui il commit altrimenti il rollback.
    Saluti a tutti
    Riccardo

  7. #7
    Utente di HTML.it
    Registrato dal
    Mar 2009
    Messaggi
    174
    idAccount è di tipo INT(10) sul db e per l'inserzione uso questa funzione che ho testato e che riporta correttamente un valore intero
    codice:
        int getAccountId(String username) {
            int id = -1;
            String query = "SELECT id FROM srt_accounts WHERE username='" + codificaApici(username) + "'";
            Connection conn = null;
            Statement stmt = null;
            ResultSet rs = null;
            try {
                conn = DriverManager.getConnection(strConn, dbuser, dbpassword);
                stmt = conn.createStatement();
                rs = stmt.executeQuery(query);
                if (rs.next()) {
                    id = rs.getInt(1);
                }
            } catch (SQLException e) {
                System.err.println(e.getLocalizedMessage());
            } finally {
                if (rs != null) { try { rs.close(); } catch (SQLException ignore) { System.err.println(ignore.getLocalizedMessage()); }}
                if (stmt != null) { try { stmt.close(); } catch (SQLException ignore) { System.err.println(ignore.getLocalizedMessage()); }}
                if (conn != null) { try { conn.close(); } catch (SQLException ignore) { System.err.println(ignore.getLocalizedMessage()); }}
            }
            return id;
        }
    anche a me suona strano, ma se metto le commit e tutte e due le insert vanno a buon fine non mi compare l'errore se le metto ecco che risalta fuori

  8. #8
    Utente di HTML.it
    Registrato dal
    Mar 2009
    Messaggi
    174
    Se non metto la commit la funzione mi ritorna -1 che non viene accettato dal db perchè idaccount è un int(10) unsigned. Il recupero dell'id viene fatto ma non essendo stata committata la prima insert si ha un riscontro negativo perchè la tabella non contiene il valore cercato.

  9. #9
    Originariamente inviato da Hermiod
    idAccount è di tipo INT(10) sul db e per l'inserzione uso questa funzione che ho testato e che riporta correttamente un valore intero
    codice:
        int getAccountId(String username) {
            int id = -1;
            String query = "SELECT id FROM srt_accounts WHERE username='" + codificaApici(username) + "'";
            Connection conn = null;
            Statement stmt = null;
            ResultSet rs = null;
            try {
                conn = DriverManager.getConnection(strConn, dbuser, dbpassword);
                stmt = conn.createStatement();
                rs = stmt.executeQuery(query);
                if (rs.next()) {
                    id = rs.getInt(1);
                }
            } catch (SQLException e) {
                System.err.println(e.getLocalizedMessage());
            } finally {
                if (rs != null) { try { rs.close(); } catch (SQLException ignore) { System.err.println(ignore.getLocalizedMessage()); }}
                if (stmt != null) { try { stmt.close(); } catch (SQLException ignore) { System.err.println(ignore.getLocalizedMessage()); }}
                if (conn != null) { try { conn.close(); } catch (SQLException ignore) { System.err.println(ignore.getLocalizedMessage()); }}
            }
            return id;
        }
    anche a me suona strano, ma se metto le commit e tutte e due le insert vanno a buon fine non mi compare l'errore se le metto ecco che risalta fuori
    prova a stamparti a video l'id che provi ad inserire vedi cosa ottieni
    http://www.anobii.com/isalreadyinuse

  10. #10
    I dati che hai inserito o modificato con la transazione A non sono visibili alla transazione B fintantochè non chiudi la transazione con il commit o non agisci sul livello di isolamento. Dovresti quindi evitare di aprire una nuova connection, cosa che fai nella funzione che hai indicato, per fare una query sulla tabella ed ottenere un valore che è in corso di modifica nella transazione principale. Dovresti fare tutto nella stessa transazione ed ecco che non avresti più bisogno di committare la prima query per renderla visibile dalla tua funzione.
    Saluti a tutti
    Riccardo

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 © 2020 vBulletin Solutions, Inc. All rights reserved.