Discussione:
Gestione accessi concorrenti al database
(troppo vecchio per rispondere)
Andrea Barbagallo
2006-03-29 16:53:17 UTC
Permalink
Ciao a tutti.
Vorrei qualche consiglio sulla politica da adottare nello sviluppo di
un'applicazione per gestire gli accessi concorrenti di piu' utenti allo stesso
database nell'ambito di un'architettura di tipo client-server. Il tutto,
possibilmente, senza doversi necessariamente legare ad uno specifico database.

Grazie per l'attenzione
Andrea Barbagallo
Andrea Barbagallo
2006-03-29 20:29:19 UTC
Permalink
Scusatemi: ho riletto il mio post precedente ed ammetto di essere stato
estremamente vago. Provero' ad essere piu' chiaro.

Premetto che vorrei realizzare un'applicazione di tipo gestionale per aziende
(es. fatturazione e magazzino) che sia il piu' possibile indipendente dal tipo
di database utilizzato per contenere i dati ed il piu' possibile "scalabile".
Col termine scalabile intendo la possibilita' di poter funzionare sia
utilizzando un database dBase in monoutenza su un singolo pc, sia utilizzando
come database Access condiviso in multiutenza da due soli pc messi in rete, sia
collegandosi ad un server Oracle in uno scenario in cui, con la stessa
applicazione, centinaia di utenti della stessa rete di pc accedono al medesimo
database.

Tenendo presente questi obiettivi ideali (che probabilmente non sono
realizzabili del tutto ma da cui comunque non vorrei discostarmi troppo) mi
chiedo quali siano le tecniche di programmazione piu' efficaci per gestire il
problema degli accessi concorrenti di piu' utenti agli stessi dati.

So che spesso la tecnica usata e' quella di impostare un lock fisico sul record
quando l'utente inizia a modificarne i campi e mantenerlo fino alla pressione
del tasto "salva". In questo modo, se un altro utente prova contemporaneamente a
modificare lo stesso record, sul tentativo di impostare un nuovo lock si riceve
un errore dal database; tale errore viene gestito dal programmatore avvertendo
il secondo utente che il suo tentativo di modifica verra' annullato perche' i
dati sono gia' bloccati in scrittura. A me pero' questo approccio non piace per
i seguenti motivi:
1) viene meno al requisito di indipendenza da uno specifico database (o RDBMS)
poiche' le tecniche per impostare i lock fisici sui record variano da un
database all'altro (o sbaglio?);
2) su alcuni tipi di database la gestione dei lock a livello di singolo record
e' mal gestita o del tutto assente.

Un altro sistema a cui avrei pensato per risolvere il problema e' quello di
seguito descritto e consiste nel farsi una propria gestione dei lock (lock
"logici") evitando di loccare fisicamente il record e conservando in una tabella
l'elenco aggiornato dei record su cui si stanno effettuando delle modifiche.
Ecco i passaggi fondamentali di questa tecnica:
1) Quando l'utente inizia a scrivere sul campo di una maschera di input per
modificare un record viene, viene effettuato il controllo descritto al punto 2 e
- in caso di esito positivo - si inserisce un record in un'apposita tabella
(presente nello stesso db e dedicata esclusivamente alla gestione dei lock
logici) per segnare che un certo id utente sta bloccando in scrittura un record
con un certo id presente nella tabella X.
2) La modifica o la cancellazione di un record x vengono consentiti solo se,
nell'apposita tabella descritta al punto 1, non sono presenti registrazioni
contenenti l'id del record x. Nel caso in cui almeno una registrazione sia
presente, dalla stessa tabella viene letto l'id utente corrispondente al lock
riscontrato e si mostra all'utente un messaggio di errore del tipo "Permesso in
scrittura negato: l'utente Mario sta bloccando il record corrente".
3) Quando l'utente del punto 1 ha finito di modificare i campi e preme il
pulsante "Salva", i nuovi dati vengono scritti sul record e si elimina la
registrazione del lock logico dall'apposita tabella descritta al punto 1.

Tuttavia quest'ultima soluzione dovrebbe essere implementata da zero.
Mi chiedevo quindi se esistessero ulteriori tipi di approcci al problema e
magari delle tecnologie/tool/librerie gia' pronte per gestire gli accessi
concorrenti rispettando il piu' possibile gli obiettivi precedentemente enunciati.

Ciao
Andrea Barbagallo
Luca Pascali
2006-03-29 21:08:46 UTC
Permalink
Post by Andrea Barbagallo
Scusatemi: ho riletto il mio post precedente ed ammetto di essere stato
estremamente vago. Provero' ad essere piu' chiaro.
Premetto che vorrei realizzare un'applicazione di tipo gestionale per
aziende (es. fatturazione e magazzino) che sia il piu' possibile
indipendente dal tipo di database utilizzato per contenere i dati ed il
piu' possibile "scalabile".
[...]
Post by Andrea Barbagallo
Ciao
Andrea Barbagallo
Non ho letto tutto il tuo post, ma ci sono un paio di cose che ho letto
che mi hanno fatto un po' rabbrividire.

Prima cosa la scelta del database. Nomini Access con accesso multiutenza.
A questo punto, perchè non passare ad un database serio e non una cosa
che gli assomiglia poco e male? (per favore non lanciate flame. Access
*non* *è* un database relazionale degno di questo nome. Per non parlare,
poi, della sicurezza dei dati).

Ci sono diverse soluzioni, free e non, sia in mondo M$ che al di fuori
di esso.

Se proprio vuoi rimanere in mondo M$, ti consiglio MSDE. Si tratta del
motore di SQL Server, senza tutti i programmi di contorno. Oppure
potresti muoverti verso PostgreSql (ottimo) o MySQL (altro db buono).

I vantaggi principali sono
1) avere database seri che ti garantiscono anche che i dati non vanno
persi per colpa di un accesso contemporaneo al file di DB.
2) (su Postgres ci sono, su MSDE dovrebbero esserci e su MySQL non so)
puoi impostare vincoli di integrità referenziale tra le tabelle,
impostare indici per un accesso migliore alle tabelle, gestire trigger
per effetturare operazioni particolari prima o dopo le query in modo
automatico (come per esempio mettere in pista un "cestino" o bloccare
una update se il record è già stato finalizzato)
3) (anche qui non credo che MySQL abbia qualcosa di simile, ma mi posso
sbagliare) puoi usare delle stored procedure (non so come le chiami
MSDE), ossia codice che salvato nel database ed eseguito dal database,
ti permette di automatizzare tutta una serie di operazioni.
4) manutenzione più facile
5) accesso con username e password per la protezione dei dati (puoi
anche impostare utenti che hanno solo diritti di interrogazione)
6) prestazioni migliori

e tanti altri vantaggi.

In più, MSDE e PostgreSQL (anche MySQL, ma solo con l'ultimo tipo di
database che hanno aggiunto nella versione 4 o 5) supportano già le
transazioni, ossia permettono l'accesso simultaneo al database a più
utenti (e non parlo di solamente 2 utenti) interbloccando
automaticamente le operazioni di selezione e modifica, solo se queste
avvengono sugli stessi elementi, e permettendoti di confermare o
annullare l'intera sequenza di modifiche all'ultimo momento (apri la
transazione, fai una serie di query, nessun altro può modificarti i dati
sotto al naso, trovi che esiste una condizione che non ti piace o non
piace al db, come una foreign key non valida, annulli la transazione e
nessuna modifica è stata fatta al DB, oppure se non ci sono errori,
confermi la transazione. Quando la transazione termina, gli altri
possono accedere a quei record e continuare il loro lavoro come se nulla
fosse).

Come metodo di accesso, poi, puoi considerare l'uso delle ODBC (un po'
pesantine, a mio parere, ma ti permettono di astrarti sufficientemente
dal tipo di database che stai utilizzando).

Ultima cosa, ma non per importanza, un database serio come quelli che ti
ho elencato, può stare anche su un'altra macchina collegata in rete.
Access aveva problemi di corruzione del file di dati (non so se questo
baco sia stato corretto o no) in caso di accessi da rete.

Spero di esserti stato utile.

Luca
RobertoA
2006-03-29 23:07:39 UTC
Permalink
Post by Andrea Barbagallo
1) Quando l'utente inizia a scrivere sul campo di una maschera di input
per modificare un record viene, viene effettuato il controllo descritto al
punto 2 e - in caso di esito positivo - si inserisce un record in
un'apposita tabella (presente nello stesso db e dedicata esclusivamente
alla gestione dei lock logici) per segnare che un certo id utente sta
bloccando in scrittura un record con un certo id presente nella tabella X.
2) La modifica o la cancellazione di un record x vengono consentiti solo
se, nell'apposita tabella descritta al punto 1, non sono presenti
registrazioni contenenti l'id del record x. Nel caso in cui almeno una
registrazione sia presente, dalla stessa tabella viene letto l'id utente
corrispondente al lock riscontrato e si mostra all'utente un messaggio di
errore del tipo "Permesso in scrittura negato: l'utente Mario sta
bloccando il record corrente".
3) Quando l'utente del punto 1 ha finito di modificare i campi e preme il
pulsante "Salva", i nuovi dati vengono scritti sul record e si elimina la
registrazione del lock logico dall'apposita tabella descritta al punto 1.
Non funzia.
Perche' potrebbero essere contemporaneamente due client a testare '...se
nell'apposita tabella sono presenti registrazioni contenenti l'id del record
x...' e quindi a pensare che il tal record sia disponibile per la scrittura
e quindi entrare in scrittura su quel record, sbagliando.
Non e' possibile eseguire la trafila:
- vedo se e' disponibile
- se disponibile entro in scrittura
Perche' nel tempo che passa dalla prima operazione alla seconda, qualche
altro client potrebbe essere entrato in scrittura sullo stesso record.
E per quanto improbabile sia, ti assicuro che se puo' succedere, allora
succede (prima reg. di Murphy) e se sei sfortunato succede il pomeriggio
prima della sera che dovevi incassare l'acconto del programma appena
consegnato (seconda di Murphy), soldi che servivano per fare bella figura e
portare a cena con la tua nuova morosa (terza di Murphy) .
Se vuoi che non succeda, deve essere impossibile che succeda, ma proprio
tecnicamente impossibile, bachi di Windows a parte (quarta di Murphy).
L'unico modo che hai di realizzare una concorrenza robusta e' di verificare
se ti viene restituito un errore quando tenti di scrivere sul record
(concorrenza ottimistica) e reagire di conseguenza, oppure lockare quel
record, lavorarci sopra, e s-lockarlo quando hai finito le operazioni
(concorrenza pessimistica).
Personalmente ti consiglio la prima possibilita', non blocchi nessuno, ti
permette un'alto livello di concorrenza delle operazioni, anche se devi
lavorare maggiormente sul '...reagire di conseguenza...', devi quindi
prevedere una casistica piu' ampia di possibili risultati al tentativo di
update e gestirli correttamente, quindi forse un pelino piu' laboriosa da
implementare ma sicuramente piu' efficace nell'utilizzo reale
dell'applicazione.
Di piu' nin-tzoo.
Ciao
RobertoA
Andrea Barbagallo
2006-03-31 09:27:03 UTC
Permalink
RobertoA ha scritto:
[...]
Post by RobertoA
E per quanto improbabile sia, ti assicuro che se puo' succedere, allora
succede (prima reg. di Murphy) e se sei sfortunato succede il pomeriggio
prima della sera che dovevi incassare l'acconto del programma appena
consegnato (seconda di Murphy), soldi che servivano per fare bella figura e
portare a cena con la tua nuova morosa (terza di Murphy) .
[...]
Post by RobertoA
Di piu' nin-tzoo.
Ciao
RobertoA
Ciao anche a te e grazie per i tuoi preziosi consigli... anche da parte della
mia ragazza :-)

Andrea Barbagallo
RobertoA
2006-04-10 13:31:29 UTC
Permalink
Post by Andrea Barbagallo
Post by RobertoA
prima della sera che dovevi incassare l'acconto del programma appena
consegnato (seconda di Murphy), soldi che servivano per fare bella figura
e portare a cena con la tua nuova morosa (terza di Murphy) .
[...]
Post by RobertoA
Di piu' nin-tzoo.
Ciao
RobertoA
Ciao anche a te e grazie per i tuoi preziosi consigli... anche da parte
della mia ragazza :-)
A dire il vero qualcuno ha sentito parlare anche della quinta di Murphy che
recita piu' o meno cosi':
""...in caso vengano poste domande sulla concorrenza dei db allora la morosa
del richiedente dovra' ringraziare 'personalmente' colui la di cui risposta
verra' ritenuto un prezioso consiglio..."
Bon, ci sentiamo in privato ....
Ciao
RobertoA

Luigi Simonato
2006-03-30 16:01:21 UTC
Permalink
Post by Andrea Barbagallo
Premetto che vorrei realizzare un'applicazione di tipo gestionale per aziende
(es. fatturazione e magazzino) che sia il piu' possibile indipendente dal tipo
di database utilizzato per contenere i dati ed il piu' possibile "scalabile".
Col termine scalabile intendo la possibilita' di poter funzionare sia
utilizzando un database dBase in monoutenza su un singolo pc, sia utilizzando
come database Access condiviso in multiutenza da due soli pc messi in rete, sia
collegandosi ad un server Oracle in uno scenario in cui, con la stessa
applicazione, centinaia di utenti della stessa rete di pc accedono al medesimo
database.
Andrea Barbagallo
Middleware?
http://it.wikipedia.org/wiki/Middleware

Ma potrei aver capito male...

Saluti
JJ
--
questo articolo e` stato inviato via web dal servizio gratuito
http://www.newsland.it/news segnala gli abusi ad ***@newsland.it
Manlio Perillo
2006-03-31 09:44:22 UTC
Permalink
Post by Andrea Barbagallo
Scusatemi: ho riletto il mio post precedente ed ammetto di essere stato
estremamente vago. Provero' ad essere piu' chiaro.
Premetto che vorrei realizzare un'applicazione di tipo gestionale per
aziende (es. fatturazione e magazzino) che sia il piu' possibile
indipendente dal tipo di database utilizzato per contenere i dati ed il
piu' possibile "scalabile". Col termine scalabile intendo la
possibilita' di poter funzionare sia utilizzando un database dBase in
monoutenza su un singolo pc, sia utilizzando come database Access
condiviso in multiutenza da due soli pc messi in rete, sia collegandosi
ad un server Oracle in uno scenario in cui, con la stessa applicazione,
centinaia di utenti della stessa rete di pc accedono al medesimo database.
Una soluzione migliore e' evitare di accedere al database a "basso" livello.

Prova a definire una interfaccia per l'accesso ai tuoi dati ad alto
livello e implementa questa interfaccia per ogni database che vuoi
supportare (usando i meccanismi che ogni database offre).

Portabilita' significa anche questo, non solo scrivere del codice valido
ovunque (che, IMHO, e' una utopia).


E' una faticaccia, non l'ho mai fatto (ma l'ho proposto per lo sviluppo
di Phasis [1] anche se il progetto e' fermo da molto tempo), ma ti da
molti vantaggi, tra cui quello di poter implementare l'interfaccia
tramite RPC ed accedere in maniera trasparente ad un database in rete.


[1] http://devel.phasis.it/
E' scritto in Python, e' in fase di refactoring, ma le definizioni
(da fare) dello schema per database relazionali e della interfaccia
di accesso ai dati sono del tutto indipendenti.

Ad esempio si usa SQL (o diagrammi) per la prima e IDL per la
seconda, volendo essere pignoli.




Saluti Manlio Perillo
Loading...