Visualizzazione risultati 1 fino 18 di 18

Discussione: Modifica concorrente su tabella

  1. #1
    Guest

    Predefinito Modifica concorrente su tabella

    Un saluto.

    Spiego brevemente la mia situazione:
    Il mio database possiede una tabella contenente diversi record e in ogni record, tra gli altri, e' presente un campo chiamato quantita. Gli utenti che accedono al sito possono vedere su di una pagina tali record (e quindi anche il campo in questione), selezionarne uno (mediante apposito link) e da qui essere rimandati ad una nuova pagina dove poter scalare un certo valore a tale quantita.
    La quantita non può mai essere negativa e in tal caso l'operazione (che la farebbe diventare negativa) non può essere eseguita.

    Ora supponiamo che un record i abbia come quantita 100 e che un utente lo selezioni dalla prima pagina e che nella seconda pagina decida di scalare 80. L'operazione non crea problemi e la quantita viene aggiornata a 20.

    Se pero' l'utente tra una pagina e l'altra (quindi dopo aver selezionato il record, ma prima di confermare lo scalo di 80 alla quantita) attende un certo periodo di tempo tale che un nuovo utente riesca nel mentre a selezionare anch'esso il record i e a scalare, ad esempio, 40 confermando l'operazione, ora si avrebbe che il primo utente andrebbe, nel momento in cui finalmente conferma lo scalo, a scalare 80 dai 60 restanti (andando a -20, cosa non ammissibile) e non i soliti 80 dai 100 iniziali.

    Di fatto basterebbe che nel momento in cui si conferma lo scalo dalla quantita si potesse fare in un'unica "passata" sia un ricontrollo dell'attuale campo quantita, sia lo scalo effettivo (se questo risulta ovviamente ancora possibile).

    Utilizzando tabelle di tipo InnoDB il tutto si risolverebbe mediante transazioni, ma con tabelle di tipo MyISAM cio' non e' possibile.

    Esistono altri modi per risolvere il problema di accesso esclusivo? Eventualmente anche bloccando l'accesso alla tabella per il tempo strettamente necessario per effettuare in rapida successione le 2 operazioni di ricontrollo e scalo?

    Cercando sulla documentazione di MySql ho trovato le istruzioni GET_LOCK (str, timeout) e RELEASE_LOCK (str) ma non ho capito se e come possono risolvere questo mio problema.

    Grazie in anticipo per l'aiuto

  2. #2
    Guest

    Predefinito

    non ti conviene, ti consiglio di aggiungere un campo al record.

    il campo è 0

    quando qualcuno modifica la quantità imposta la variabile a 1

    imposti la visualizzazione in modo che se la variabile è 1 non faccia funzionare il link

  3. #3
    Guest

    Predefinito

    Nel modo che proponi pero' se un utente temporeggia anche nella prima pagina (prima di selezionare il record i) da modo anche ad altri utenti di arrivare nella sua stessa posizione e se anche il primo utente successivamente seleziona il record impostando il campo a 1, gli utenti che nel mentre erano gia' giunti alla prima pagina hanno ovviamente il link a disposizione e il problema non e' risolto

  4. #4
    Guest

    Predefinito

    ah, ma il controllo lo fai quando chiede la pagina di modifica ;) ( il link insomma )

  5. #5
    Guest

    Predefinito

    Vediamo se riesco a spiegarmi meglio

    Pagina 1: elenco record della tabella con relativi link per la modifica del campo quantita del record associato

    Pagina 2: campo con il valore da scalare al campo quantita del record selezionato

    Quello che fa l'utente e' scegliere dalla pagina 1 il record che vuole selezionando il link relativo, poi nella pagina 2 inserisce il valore da scalare e conferma. Alla conferma devo controllare il campo quantita e poi aggiornarlo se il risultato e' >=0.

    Questo comporta 2 operazioni (controllo e modifica) che andrebbero fatte con accesso esclusivo (con transazioni appunto) perche' il rischio e' di avere una sequenza di operazioni come segue (in ordine temporale):

    utente 1 esegue query di controllo (la quantita risulta 100)
    utente 2 esegue query di controllo (la quantita risulta 100)
    utente 1 vuole togliere 60 (100-60=40>0)
    utente 2 vuole togliere 80 (100-80=20>0)
    utente 1 esegue query di modifica quantita-60 (la quantita diventa 40)
    utente 2 esegue query di modifica quantita-80 (la quantita diventa -40!)

    Spero di aver reso piu' chiaro il problema perche' prima era esposto proprio male

  6. #6
    Guest

    Predefinito

    prova a fare in questo modo, manda il controllo quando premono aggiorna in pagina 2 ( prima di cambiare il dato controlla che il risultato sia positivo )

  7. #7
    Guest

    Predefinito

    Forse non ho ben compreso cosa intendi ma quanto dici e' proprio cio' che faccio attualmente.

    La sequenza di operazioni che ho postato poco fa riguardo all'interazione contemporanea di 2 (o peggio piu') utenti avviene proprio quando si da conferma nella pagina 2 per aggiornare il campo quantita

  8. #8
    Guest

    Predefinito

    in pratica, devi mettere all'inizio della terza pagina ( quella che manda il query sql ) che prima deve far un altro query, che se (IF) il valore di quello del record è maggiore della diminuzione (ALLORA) diminuisce altrimenti (ELSE) non fa niente ^__^

  9. #9
    Guest

    Predefinito

    Ok, allora avevo compreso correttamente.
    Il problema che mi pongo pero' e' proprio li' e cioe' che per fare questo devo eseguire 2 query al database slegate tra loro: la prima per controllare l'attuale valore, mentre la seconda (se il valore da scalare e' corretto) per aggiornare il valore.
    Ma se un altro utente effettua il suo controllo tra la mia prima e la mia seconda query si crea inconsistenza di dati, che e' proprio quello che non posso permettermi di avere quindi questa soluzione purtroppo non mi risolve il problema

  10. #10
    Guest

    Predefinito

    Aspetta, allora prova così, la prima query controlla il record (se visualizzazione è a 0 ) ed imposta una variabile a valore 1 ( diciamo visualizzazione ), se si può scalare, scala e rimette 0, altrimenti rimette solo il valore 0

    Spero di essermi spiegato

  11. #11
    Guest

    Predefinito

    Certo ma cosi' sposti solo il problema dal campo quantita a questo nuovo campo perche' ti servira' comunque una query per controllare che questo nuovo valore sia 0 e un'altra query per impostarla a 1 per poi effettuare le eventuali modifiche e nuovamente un secondo utente potrebbe effettuare il suo controllo su questo nuovo campo proprio tra la mia prima e la mia seconda query creando inconsistenza proprio su questo campo aggiuntivo che proponi

  12. #12
    Guest

    Predefinito

    Questo campo aggiuntivo lo potresti però usare come accesso prioritario al file, tu con la prima query prendi tutti i dati, poi nel programma php fai delle strutture di controllo, se vanno bene allora e solo allora aggiorna i dati ( mettendo il file in blocco, ricontrollando il dato ed aggiornandolo alla riga successiva per poi sbloccare il record ). altrimenti conclude la pagina con un errore se il dato che vuoi mettere già all'inizio è sbagliato... sinceramente più che questo non saprei che dirti...

  13. #13
    Guest

    Predefinito

    A parte che non capisco da dove arriva questo file di cui ora parli, ma appunto la mia richiesta iniziale era un sistema per poter effettuare un blocco sui dati che ho per effettuare un accesso esclusivo

    Dalle guide mySql ho proprio trovato le istruzioni GET_LOCK e RELEASE_LOCK che sembra dovrebbero effettuare questo blocco ma purtroppo non capisco in che modo usarle

  14. #14
    Guest

    Predefinito

    Ho letto appena adesso quell'articolo, in pratica blocchi tutta la tabella, ma nei commenti ci sono delle cose da prendere in considerazione per lo sblocco ma non riesco a tradurlo meglio "^_^

  15. #15
    Guest

    Predefinito

    A quanto mi ricordo, mySql lavora con thread di operazioni, quindi non avviene mai in contemporanea una scrittura sulla tabella. Puoi fare un semplice controllo nel visualizzarlo, se è 0 o minore lui scrive 0 lo stesso e ti basi su questo. Non metti un controllo preciso del tipo
    Codice PHP:
    if ($var == 0)
    ma
    Codice PHP:
    if ($var <= 0)
    e dovresti risolvere il tuo problema così...

    Sempre se ho capito bene

  16. #16
    Guest

    Predefinito

    Perdonami, sara' anche l'ora, ma non capisco a cosa ti riferisci con le istruzioni condizionali che hai riportato e con il discorso in generale
    Riesci ad essere un pochino piu' chiaro? Grazie

    Soprattutto quel <= proprio non riesco a inquadrarlo ne' nell'esempio che ho riportato per spiegare il problema che ho e nemmeno nella soluzione iniziale proposta da laguida

  17. #17
    Guest

    Predefinito

    Citazione Originalmente inviato da vse
    Perdonami, sara' anche l'ora, ma non capisco a cosa ti riferisci con le istruzioni condizionali che hai riportato e con il discorso in generale
    Riesci ad essere un pochino piu' chiaro? Grazie

    Soprattutto quel <= proprio non riesco a inquadrarlo ne' nell'esempio che ho riportato per spiegare il problema che ho e nemmeno nella soluzione iniziale proposta da laguida
    No, non ho capito bene il tuo problema... Scusami, rileggo e cerco una soluzione

    @edit: Ok, riletto... A te serve che il controllo sulla quantità sia in tempo reale, cioè nel momento in cui sceglie la quantità... Credo che per una cosa simile tu debba utilizzare Ajax... Nel momento in cui preme sul submit del form, con ajax lanci una pagina php che ti ritorni la quantità disponibile e se maggiore o uguale a 0 continui con lo script... Oppure scoprire come utilizzare le funzioni GET_LOCK e RELEASE_LOCK... Magari posta il link della documentazione
    Ultima modifica di neoscript : 11-05-2006 alle ore 23.56.31

  18. #18
    Guest

    Predefinito

    Ho letto il tuo primo post ma non ho avuto il tempo di leggere quanto ti hanno detto gli altri quindi è possibile che stia ripetendo quanto dettoti da qualcuno..
    Io personalmente eseguirei una nuova query subito PRIMA di effettuare QUALSIASI variazione di quantità... In fondo che controindicazione c'è a fare così? Solo il fare una query in piu?... naaa...

    EDIT: Ho riletto i post degli altri utenti, quoto in pieno quanto dice "laguida" è sicuramente ciò che fa per te
    Ultima modifica di attorianzo : 12-05-2006 alle ore 08.58.12 Motivo: modifica successiva

Regole di scrittura

  • Non puoi creare nuove discussioni
  • Non puoi rispondere ai messaggi
  • Non puoi inserire allegati.
  • Non puoi modificare i tuoi messaggi
  •