Lock Record SQL

di il
12 risposte

Lock Record SQL

Ciao ragazzi,
vorrei sapere come posso fare per allocare in modo esclusivo un record su DB SQL .

Cerco di spiegarmi meglio.

Vorrei leggere un record da SQL e visualizzare i dati a video.

Oltre alla visualizzazione vorrei poter consentire anche la modifica dei dati con successivo update sul DB.

Dal momento in cui eseguo la lettura al momento in cui eseguo l'update del record il record stesso dovrebbe essere il sola lettura per gli altri utenti altrimenti potrei rischiare di avere dati incongruenti.

Ho fatto alcune prove in update ed ho notato che una volta eseguito i comando "ExecuteNonQuery" il record è bloccato fino a quando non eseguo la commit ma non mi sembra la strada giusta da seguire.

Come posso fare?

Grazie.

Alberto

12 Risposte

  • Re: Lock Record SQL

    Alberto75 ha scritto:


    vorrei sapere come posso fare per allocare in modo esclusivo un record su DB SQL .
    Mi pare tutto fuorché una buona idea, soprattutto con i database di tipo SQL.

    Alberto75 ha scritto:


    Dal momento in cui eseguo la lettura al momento in cui eseguo l'update del record il record stesso dovrebbe essere il sola lettura per gli altri utenti altrimenti potrei rischiare di avere dati incongruenti.
    Mi viene spesso chiesta da clienti e tento di scoraggiare in qualsiasi modo questo approccio, spesso senza successo, poiché limita inutilmente l'operatività a fronte di un problema che è solo di comunicazione nella maggior parte delle volte.

    Tra l'altro, molti framework ORM sono in grado di sopperire a questa mancanza, andando ad aggiornare solo i campi modificati e conservando quindi di fatto le modifiche apportate da più utenti, a meno che non siano tutte riferite allo stesso campo, condizione che appunto evidenzia un problema di comunicazione e di organizzazione, e non un problema software.

    Alberto75 ha scritto:


    Ho fatto alcune prove in update ed ho notato che una volta eseguito i comando "ExecuteNonQuery" il record è bloccato fino a quando non eseguo la commit ma non mi sembra la strada giusta da seguire.
    Questo è esattamente ciò a cui mi riferivo sopra: le problematiche di gestione di questo approccio a livello software introducono potenziali colli di bottiglia e rischi di "deadlock" pressoché inutili, limitando di fatto il beneficio di avere a disposizione un server SQL e rendendo il software assolutamente non-scalabile.

    Alberto75 ha scritto:


    Come posso fare?
    L'unica soluzione efficace che ho trovato nell'ambito della realizzazione di un'applicazione Web dove il cliente non ha voluto sentire ragioni è quella di aggiornare periodicamente il record (es. ogni 10 secondi) che l'utente sta modificando a video, inserendo in un campo apposito la data/ora in cui si è verificato questo "ping" di segnalazione di modifica.

    Le altre postazioni leggono il record assieme a questo campo e, se vedono che dalla data/ora di modifica inserita non è trascorso un certo lasso di tempo (es. 30 secondi), segnalano che il record potrebbe essere in corso di modifica da parte di un altro utente; se invece il tempo prestabilito è trascorso, non viene fatta alcuna segnalazione.

    A fronte di dover aggiornare periodicamente il campo del record, soluzione che reputo assolutamente inefficiente, si ottiene il vantaggio di poter segnalare l'eventuale modifica da parte di un altro utente, ed eventualmente anche di chi (se si include il dato nei campi memorizzato), e nel caso in cui l'applicazione vada in crash o smetta di aggiornare il record, questo diventa automaticamente "libero" dopo pochi secondi, senza che sia necessario un intervento amministrativo o che si debba ricordare di aggiornare di nuovo il record quando le modifiche sono terminate.

    La soluzione funziona senza problemi, ma non sono felice di averla implementata, poiché sono ben conscio delle limitazioni che ha.

    Ciao!
  • Re: Lock Record SQL

    Volendo si potrebbe usare il rowversion.
    Nella lettura ti porti dietro il rowversion, per la scrittura usi una transazione che controlla il rowversion del record. Se non è cambiato finalizzi la transazione. Se è cambiato annulli e riporti a video dell'utente i dati che sono cambiati. L'utente compara i dati cambiati e sceglie se dare per buoni i suoi o quelli del database. C'è da intervenire ovviamente sulla maschera di data entry.
  • Re: Lock Record SQL

    Grazie mille per la pronta risposta.

    La soluzione proposta da Toki potrebbe essere una soluzione anche se comunque l'utente che esegue il secondo aggiornamento sarebbe costretto a revisionare i dati inseriti e quindi potrebbe non essere la soluzione ottimale.

    Io avevo pensato di aggiornare un campo del record con un carattere che mi indica che quel record è bloccato/impegnato e quindi le successive letture che verranno fatte sono limitate alla sola lettura in base al valore di questo campo...ma non so se è una cosa praticabile.

    A questo punto chiedo ad Alka che ha già affrontato la questione che soluzioni suggerisci per evitare che si verifichi che uno dei 2 aggiornamenti venga perso.

    Faccio un esempio per spiegarmi meglio.

    Utente1 legge un record con quantità 10 e visualizza questo valore a video.
    Utente 2 legge lo stesso record che ha ancora quantità 10 perchè non è ancora stato aggiornato da utente1 e a video avrà quindi 10.
    Utente 1 modifica la quantità a 15 ed esegue l'aggiornamento.
    Ora la quantità nel DB è 15
    Utente 2 modifica la quantità a video( che è 10) con 13 ed esegue l'aggiornamento e quindi il valore sul DB è 13.
    Alla fine la quantità sul DB è 13 e le 5 unità che aveva incrementato utente1 sono andate perse.
    Questo è querllo che vorrei evitare.

    Cosa mi suggerisci di fare.

    Grazie

    Alberto
  • Re: Lock Record SQL

    Toki ha scritto:


    Nella lettura ti porti dietro il rowversion, per la scrittura usi una transazione che controlla il rowversion del record. Se non è cambiato finalizzi la transazione. Se è cambiato annulli e riporti a video dell'utente i dati che sono cambiati. L'utente compara i dati cambiati e sceglie se dare per buoni i suoi o quelli del database. C'è da intervenire ovviamente sulla maschera di data entry.
    Questa è senz'altro la soluzione che preferisco in termini di implementazione: non bloccante, aperta, facile da implementare per la riconciliazione senza dover verificare tutti i campi modificati.
  • Re: Lock Record SQL

    Alberto75 ha scritto:


    Io avevo pensato di aggiornare un campo del record con un carattere che mi indica che quel record è bloccato/impegnato e quindi le successive letture che verranno fatte sono limitate alla sola lettura in base al valore di questo campo...ma non so se è una cosa praticabile.
    E' praticabile, ma se per qualche motivo non resetti quel campo il record rimarrà sempre "bloccato".

    Alberto75 ha scritto:


    A questo punto chiedo ad Alka che ha già affrontato la questione che soluzioni suggerisci per evitare che si verifichi che uno dei 2 aggiornamenti venga perso.
    Mi pareva di averla già scritta.

    Alberto75 ha scritto:


    Faccio un esempio per spiegarmi meglio.

    Utente1 legge un record con quantità 10 e visualizza questo valore a video.
    Utente 2 legge lo stesso record che ha ancora quantità 10 perchè non è ancora stato aggiornato da utente1 e a video avrà quindi 10.
    Utente 1 modifica la quantità a 15 ed esegue l'aggiornamento.
    Ora la quantità nel DB è 15
    Utente 2 modifica la quantità a video( che è 10) con 13 ed esegue l'aggiornamento e quindi il valore sul DB è 13.
    Alla fine la quantità sul DB è 13 e le 5 unità che aveva incrementato utente1 sono andate perse.
    Questo è querllo che vorrei evitare.

    Cosa mi suggerisci di fare.
    Se vuoi impedire la modifica di un record mentre l'altro utente sta facendo modifiche, la soluzione te l'ho data nel messaggio precedente.
    Se invece vuoi riconciliare le modifiche come hai descritto, che secondo me è quella più funzionale e migliore, la soluzione è quella di Toki.

    Non c'è una "bacchetta magica" che la implementa in automatico.

    Ciao!
  • Re: Lock Record SQL

    A questo punto direi che la soluzione di Toki è quella che fa al caso mio quindi ora mi do da fare nel provare il parametro rowversion.

    Come sempre siete UNICI.

    Grazie grazie e grazie ancora.

    Alberto
  • Re: Lock Record SQL

    Ciao a tutti, premetto che le soluzioni proposte sono ovviamente meglio delle mie, volevo condividere il pensiero con il quale ho risolto una cosa simile... simile non è uguale ovvio...

    Nel mio caso era un gestionale per il magazzino e avendolo in lan ho pensato al problema della differenza tra ciò che hai caricato a video e quello che potrebbe essere cambiato nel DB

    quindi ho posto delle condizioni, aumento\diminuisco solo la quantità e non metto il totale che lo calcola il codice.
    Nel tasto ho inserito:
    1 blocco la scrittura nel campo
    2 leggo che numero è
    3 aggiungo\sottraggo
    4 riscrivo il DB e mostro a video
    5 rimetto il campo in scrittura aperta

    così, almeno io, ho risolto il fatto che il totale è comunque corretto, anche se 1 secondo prima è stato modificato e non lo vedo.

    in più, se nella scrittura trovo il campo in solo lettura, il codice riprova dopo 1 o 2 secondi (perchè qualcuno sta modificando)
    per le mie esigenze è ottimo, ma se vuoi mettere il totale a mano allora è diverso

    Chiedo a voi esperti... è utile o va bene solo per me?
  • Re: Lock Record SQL

    orione1976 ha scritto:


    in più, se nella scrittura trovo il campo in solo lettura, il codice riprova dopo 1 o 2 secondi (perchè qualcuno sta modificando)
    e se l'utente dimentica la maschera aperta quando va a prendere il caffè?
    Gli altri utenti restano nel loop dei 2 secondi perchè il tizio di prima ha lasciato in edit (virtuale) il record?
    Inoltre maggiori sono gli utenti che utilizzano il sistema e maggiori sono le probabilità che questo accada
  • Re: Lock Record SQL

    Toki ha scritto:


    orione1976 ha scritto:


    in più, se nella scrittura trovo il campo in solo lettura, il codice riprova dopo 1 o 2 secondi (perchè qualcuno sta modificando)
    e se l'utente dimentica la maschera aperta quando va a prendere il caffè?
    Gli altri utenti restano nel loop dei 2 secondi perchè il tizio di prima ha lasciato in edit (virtuale) il record?
    Inoltre maggiori sono gli utenti che utilizzano il sistema e maggiori sono le probabilità che questo accada
    No capo... perchè ho messo il coeice di sblocco in voda nel pulsante salva, quindi o non salvi e gli altri hanno via libera o salvi e si sblocca in automatico non é legato ad una maschera che può rimanere aperta
  • Re: Lock Record SQL

    I capi lasciamoli nelle piccionaie...

    vediamo di capire come funziona il tuo meccanismo ipotizzando questo flusso:
    T1: utente1 carica i dati d1 in maschera
    T2: utente1 edita i dati presenti nella maschera
    T3: utente2 carica i dati d1 in maschera
    T4: utente1 salva i dati d1 (modificati nella propria maschera) nel db e che chiameremo quindi d2
    T5: utente2 salva i dati d1 (modificati nella propria maschera) nel db e che chiameremo quindi d3

    Nell'istante T5 cosa succede?
    L'utente2 ha sovrascritto e non tenuto conto dell'operato dell'utente1?
  • Re: Lock Record SQL

    Toki ha scritto:


    I capi lasciamoli nelle piccionaie...

    vediamo di capire come funziona il tuo meccanismo ipotizzando questo flusso:
    T1: utente1 carica i dati d1 in maschera
    T2: utente1 edita i dati presenti nella maschera
    T3: utente2 carica i dati d1 in maschera
    T4: utente1 salva i dati d1 (modificati nella propria maschera) nel db e che chiameremo quindi d2
    T5: utente2 salva i dati d1 (modificati nella propria maschera) nel db e che chiameremo quindi d3

    Nell'istante T5 cosa succede?
    L'utente2 ha sovrascritto e non tenuto conto dell'operato dell'utente1?
    Che riporto il valore di sola lettura in false... forse ho dimenticato di dirlo... sorry
  • Re: Lock Record SQL

    Forse mi sono spiegato male, siccome è un iperazuone che impiega sotto il secondo normalmente ma potrebbe essere piu lunga, in nello stesso evento del button metto, blocvo scrittura
    Lettura
    Aggiunta o sottrazione
    Riscrittura
    Riporto il parametro in solo lettura false e possibilmente mostro il nuovo valore che è per forza corretto
Devi accedere o registrarti per scrivere nel forum
12 risposte