• User

    Dati in eccesso in tabella database, può generare errori?

    Salve a tutti, vi espongo subito il dubbio che ho....

    Ho creato un sito in php/mysql che permette di prenotare campi da gioco e pagare direttamente online, da alcuni giorni ho un problema particolare e vorrei un confronto con gli utenti del forum.

    All'interno del programma che gestisce la prenotazione ho creato una tabella che mi permette di prevenire il problema delle prenotazioni multiple bloccando momentaneamente i campi che si avrebbe intenzione di prenotare e cancellando tali dati una volta effettuato il pagamento..... il passaggio successivo permette di stoccare la prenotazione effettiva nella tabella di competenza.

    Il problema presentatosi riguarda alcune prenotazioni effettivamente pagate ma non presenti all' interno del database, come se all' interno del processo qualcosa bloccasse quel passaggio, contemporaneamente noto che in una tabella del database compaiono un tot di DATI IN ECCESSO !!!

    La mia domanda è la seguente:
    Avere dati in eccesso all' interno di una tabella utilizzata nel processo di registrazione di una prenotazione può creare problemi nel salvataggio / cancellazione di tali dati? Se si cosa consigliate di fare per prevenire tale problema??

    Chiedo scusa se mi sono dilungato nella spiegazione ma era necessario spiegare il contesto!

    Grazie mille a tutti!


  • User Attivo

    Ciao degrelle,

    @degrelle said:

    Il problema presentatosi riguarda alcune prenotazioni effettivamente pagate ma non presenti all' interno del database, come se all' interno del processo qualcosa bloccasse quel passaggio, contemporaneamente noto che in una tabella del database compaiono un tot di DATI IN ECCESSO !!!

    quando fai movimentazioni su una tabella MyISAM (UPDATE, DELETE), questa si frammenta lasciando degli spazi inutilizzati per un po' di tempo, fino a che altre successive INSERT non "coprono" quegli spazi. Se una tabella da 1MB ha 50kB in eccesso, significa che ha subito una serie di operazioni per le quali 50kB di dati rimossi non sono stati ancora riutilizzati (ma solamente flaggati come "spazio libero"), e quindi la tabella in quel momento sta occupando 50kB di troppo. Questo problema è facilmente risolvibile avviando una query di tipo OPTIMIZE

    OPTIMIZE TABLE nome_tabella
    

    Questo non ha nulla a che vedere col fatto che determinate transazioni di pagamento non si sono concluse con una scrittura di un record nel tuo db. Puoi postarci il codice che si occupa di fare la INSERT? Così verifichiamo se ci sono condizioni/istruzioni che possono bloccare l'inserimento...


  • User

    Grazie Francesco per la risposta, incollo di seguito spezzoni di codice con relativa spiegazione.....

    Nella prima query verifico che ci sia una determinata differenza di orario e se la condizione è rispettata inserisco una serie di dati nella tabella sincro =>

    if($differenza_ora == 0){
                        // Le ore sono uguali vediamo i minuti
                        $differenza_minuti = $minuto_sincro_2 - $minuto_trovato;
                        if($differenza_minuti > 10){
                            // Inseriamo la nuova query sincro
                            $query = "INSERT INTO sincro(user_id, nome, cognome, num_op, data_prenotazione, pista, fascia_oraria, ora_sincro, minuto_sincro) VALUES('$user_id', '$nome', '$cognome', '$num_operacion', '$data_sincro_op2', '$pista_sincro_op2', '$fascia_sincro_op2', $ora_sincro_2, $minuto_sincro_2)";
                            mysql_query($query) or die("Non posso inserire report sincro, errore: ".mysql_error());
                            // Associamo i dati alla SESSION
                            $_SESSION['data_sincro_op2'] = $data_sincro_op2;
                            $_SESSION['pista_sincro_op2'] = $pista_sincro_op2;
                            $_SESSION['fascia_sincro_op2'] = $fascia_sincro_op2;
                            $_SESSION['ora_sincro_2'] = $ora_sincro_2;
                            $_SESSION['minuto_sincro_2'] = $minuto_sincro_2;
                        }else{
                            // Stampiamo un messaggio per l' utente
                            header("Refresh:4;url=xxxx.php");
                            die("<p style='text-align:center;'>Alguien est&aacute; haciendo lo mismo, int&eacute;ntalo de nuevo.<br /><a href='xxxx.php'>clic aqu&iacute;</a></p>");    
                        }
                    }
    

    Nel caso in cui il pagamento vada a buon fine la banca re-direziona l' utente su un determinato indirizzo dove avviene lo stoccaggio dei dati nella tabella prenotazioni =>

    // INSERIAMO LA PRENOTAZIONE OP1 NEL DATABASE
        $query = "INSERT INTO prenotazioni2(user_id, nome, cognome, telefono, pista, fascia_oraria, data_operazione, data_prenotazione) VALUES('$user_id', '$nome', '$cognome', '$telefono', '$pista1', '$fascia_oraria_definitiva_op1', '$data_operazione', '$data_prenotazione_op1')";
        $result = mysql_query($query);
        if(!$result){
            die("Non riesco a caricare i dati della prenotazione, errore: ".mysql_error());    
        }
    

    ....... e cancello il dato precedentemente salvato nella tabella sincro per liberare spazio =>

    $data_sincro_op1 = $_SESSION['data_sincro_op1'];
        $pista_sincro_op1 = $_SESSION['pista_sincro_op1'];
        $fascia_sincro_op1 = $_SESSION['fascia_sincro_op1'];
        $ora_sincro_1 = $_SESSION['ora_sincro_1'];
        $minuto_sincro_1 = $_SESSION['minuto_sincro_1'];
        $query = "DELETE FROM sincro WHERE data_prenotazione = '$data_sincro_op1' AND pista = '$pista_sincro_op1' AND fascia_oraria = '$fascia_sincro_op1' AND ora_sincro = '$ora_sincro_1' AND minuto_sincro = '$minuto_sincro_1'";
        mysql_query($query) or die("Non riesco a cancellare la prima operazione sincro, errore: ".mysql_error());
    
    

    Per la cronaca ho cambiato un pò il codice ripulendolo un po e sono passato ad InnoDB per la tabella sincro (ho letto da qualche parte che sarebbe meglio) ma sono aperto a suggerimenti.

    Grazie a tutti coloro che risponderanno.


  • User Attivo

    Non riesci a venirne a capo perché non hai delle istruzioni che ti facciano da debug. Se nel tuo server i log degli errori sono impostati ad un livello medio basso, potresti addirittura non trovare traccia di eventuali errori non-FATAL. A parte l'output dato all'utente, del quale non verrai mai a conoscenza a meno che non te lo venga a dire lui, non hai dei feedback per vedere l'utente a che punto dello script è arrivato ed in quale situazione.
    Potresti dedicare un file o una tabella MySQL in cui stampi l'eventuale risultato della mysql_error(), con tanto di data ed ora, sessione utente, referrer e contenuto degli array superglobali. Non conoscendo il resto dello script, le prime cose che mi vengono in mente sono le seguenti:

    • verifica le condizioni $differenza_ora == 0 e $differenza_minuti > 10 e cerca di tracciare da qualche parte (ripeto, in un file o una tabella) gli utenti che rimangono fuori da quella condizione;
    • verifica che tutti i campi di testo implicati nella INSERT incriminata siano MySQL-friendly, ovvero che non contengano apostrofi non sottoposti ad escape prima dell'inserimento. Un utente di cognome D'Angelo, potrebbe bloccare la tua query se così non fosse, e quindi dovresti intercettare il risultato della mysql_error();

    Da ultimo, anche se non fa parte della tua richiesta, darei un'occhiata alla query in cui cancelli il record dalla tabella sincro. Anche se si tratta di una condizione molto difficile, l'unico modo per avere la certezza matematica di cancellare il solo record che vuoi cancellare e non altri record che non c'entrano nulla, è quello di mettere nella clausola WHERE la chiave primaria ed univoca. Quando inserisci il record nella tabella sincro, posto che il campo id_sincro è una chiave primaria intera AUTO_INCREMENT, con la funzione mysql_insert_id() puoi ricavare l'id del record inserito. Memorizzandolo nell'array di sessione come hai fatto per gli altri campi, puoi sfruttarlo successivamente per eseguire la query di cancellazione:

    [php]
    <?php
    // dopo l'inserimento del record nella tabella sincro...
    $_SESSION["id_sincro"] = mysql_insert_id();
    // prima la cancellazione del record dalla tabella sincro operazioni che
    $id_sincro = (int)$_SESSION["id_sincro"];
    $query = "DELETE FROM sincro WHERE id_sincro = $id_sincro";
    $result = mysql_query($query);
    // tutto il resto che manca...
    ?>
    [/php]

    così sarai sicuro di cancellare un solo record.


  • User

    Grazie mille per la disponibilità Francesco, seguirò i tuoi consigli e non appena farò ripartire il sito dallo stand-by vi aggiornerò suoi risultati.