Newsgroup: it.comp.lang.visual-basic
Titolo: [?] Server per database. Dubbio.

Ogni tanto (o poco) la mia mente si intreccia e mi impone dei quesiti che mi
stendono.
Fermo restando che il concetto dovrebbe valere per ogni tipo di
programma-server (indipendentemente dalla sua funzione), supponiamo pure di
avere un server per database (diciamo pure SQL Server). Bene, questo ha il
principale compito di "servire" i client che gli fanno delle richieste sui
dati o comandano le gestione (aggiunta, variazione, eliminazione) dei dati
stessi.
Il problema č questo: Secondo voi, ipotizzando almeno due client in
pseudo-contemporanea, le varie azioni vengono compiute "in cascata
cronologica" (prima la num.1 e, solo dopo, la num.2 e, sempre solo dopo, la
numero "n") oppure il server (supponiamolo mono-processore per non
infognarci in altro argomento) č cosě intelligente da "moltiplicarsi"
(istanziarsi?) per poter eseguire piů operazioni contemporaneamente?
Nel caso pensiate sia quest'ultima, come si concilia il fatto che un comando
dica di cancellare dei records e un altro di selezionare records che
(ipotizziamo) sono fra quelli in fase di cancellazione se si presume che il
comando di selezione possa essere eseguito durante (no, non prima o dopo, in
tal caso il comportamento sarebbe chiaro) l'esecuzione di quello di
cancellazione? Vi accontentereste di dire "seleziona quelli che trova fra
quelli ancora non cancellati"? Grazie.

 (istanziarsi?) per poter eseguire piů operazioni contemporaneamente?
Un chiaramento puň venire dalla guida in linea di SQL Server 2000, blocco
"Hint"
Per il predefinito:
READ COMMITTED
Esegue una scansione utilizzando la stessa semantica di blocco di una
transazione eseguita al livello di isolamento READ COMMITTED. Per
impostazione predefinita, viene utilizzato questo livello di isolamento.
da
SET TRANSACTION ISOLATION LEVEL
READ COMMITTED
Indica che durante la lettura dei dati vengono mantenuti blocchi condivisi
per evitare letture dirty, ma che č possibile modificare i dati prima del
termine della transazione, con la conseguente creazione di letture non
ripetibili o dati fantasma. Questa opzione corrisponde all'impostazione
predefinita di SQL Server.
------------------
Dal sopra, se non si utilizzano transazioni o blocchi Hint,
presumo sia possibile per due utenti, in contemporanea,intervenire sullo
stesso record,
in considerazione che con il blocco di default č possibile costruire
letture ripetibili o dati fantasma.
L'attendibile č eseguire
il test su due applicativi in contemporanea.
Bloccare in debug il codice nel punto interessato, in uno;
avviare il secondo e controllare il ritorno.
giuseppeD

[*Giuseppe* = 
NOSPAM...@tin.it
 in
news:YF2bb.129112$
R32.3...@news2.tin.it
] ha scritto:
...
Giuseppe, posso esprimermi (pur se simpaticamente) liberamente?
Non c'ho capito 'na mazza. ;-)
Per semplificare, facciamo finta che siano delle semplici Select (che,
quindi, non modificano i dati), secondo te (per quel che ne sai, pur dalla
guida), se due client spediscono delle richieste al server (unico e
monoprocessore), questo le esegue (lasciamo stare le modalitą e tempi di
invio dei risultati) in cascata (secondo l'ordine cronologico di
ricevimento), o potrebbe eseguirle in contemporanea?
Insomma, se a un SQL Server sono collegati 1000 client, č ipotizzabile
(oppure demenziale) che il client che ha fatto la sua richiesta dopo i
precedenti 999 debba aspettare l'esecuzione (qualunque sia la loro durata)
delle precedenti 999 richieste?

interessante questo quesito, ma con una leggera dopo-sbronza della domenica
mattina, mi è difficile rispondere....
cmq, una volta gestivo un server SQL Server per il sito 
ciakmania.it
:
avevamo anche 2.000 - 3.000 utenti contemporaneamente, ed è semplicemente
assurdo pensare che ogni utente "si mette in fila" per aspettare che gli
altri abbiano finito le loro ricerche.....
immagina, appunto, un qualsiasi sql server per un motore di ricerca: gli
utenti fanno tutto nello stesso momento, lanciano SELECT sullo stesso
database, e non c'è alcuna coda. Meno male, aggiungerei......
:-))
quindi, escluderei al 101% che il server gestisca una sorta di coda, per i
motivi detti prima.....
il meccanismo non saprei spiegarlo, però credo che ci siano tanti thread,
uno per utente.
Usando SQL Profiler, inoltre, puoi vedere quanti utenti sono connessi, e
vedere quali istruzioni SQL stanno viaggiando in quel momento sul server,
indicando anche l'utente preciso che la sta lanciando. Nel mio caso, tutti
gli utenti avevamo lo stesso username con permessi limitati read-only, però
il concetto è quello.....
good coding!!!
-- 
Damiani Liborio Igor
ig...@igordamiani.it
 - 
dam...@italiainfiera.it
 - 
idam...@hotmail.com
http://www.igordamiani.it
ICQ : 11847262
"Fabio andava bene durante il proibizionismo.
Appena si alzava, tutto il locale si girava!"
Mio fratello, 24 Agosto 2003, Ore 1:03

 delle precedenti 999 richieste?
Leggo dalla guida di SQL Server 2000
Hint per il blocco
Le istruzioni SELECT, INSERT, UPDATE e DELETE consentono di specificare una
serie di hint per il blocco a livello di
tabella in modo da indicare a Microsoft® SQL ServerT il tipo di blocco da
utilizzare. Gli hint per il blocco a livello
di tabella possono essere utilizzati quando è necessario un controllo
maggiore dei tipi di blocco applicati a un
oggetto. Questi hint sono prioritari rispetto al livello di isolamento della
transazione impostato per la sessione.
<Una considerazione: il blocco hint è prioritario rispetto al livello
d'isolamento della transazione. />
READCOMMITTED
Esegue una scansione utilizzando la stessa semantica di blocco di una
transazione eseguita al livello di isolamento READ
COMMITTED. Per impostazione predefinita, viene utilizzato questo livello di
isolamento
<Presumo (uso l'incerto perchè in questa materia ho imparato che esiste
sempre qualcuno che ne sa più di me, e un
intervento correttivo è molto gradito) che le due istruzioni seguenti siano
uguali:
1- "SELECT * FROM tabelle WHERE ID=15;"
2- "SELECT * FROM tabelle WITH (READCOMMITTED) WHERE ID=15;"
per sapere i permessi del blocco di default si segue le indicazioni:
(Esegue una scansione utilizzando la stessa semantica di blocco di una
transazione eseguita al livello di isolamento
READ COMMITTED.)
Quindi andiamo a vedere la specifica della transazione. />
SET TRANSACTION ISOLATION LEVEL
READ COMMITTED
Indica che durante la lettura dei dati vengono mantenuti blocchi condivisi
per evitare letture dirty, ma che è possibile modificare i dati prima del
termine della transazione, con la conseguente creazione di letture non
ripetibili o dati fantasma. Questa opzione corrisponde all'impostazione
predefinita di SQL Server.
<La specifica indica:
1- vengono evitate letture sporche: />
Lettura dirty
Lettura che include dati per i quali non è stato eseguito il commit. Ad
esempio, transazione1 modifica una riga. Transazione2 legge la riga
modificata prima che transazione1 esegua il commit della modifica. Se
transazione1 esegue il rollback della modifica, transazione2 ha letto una
riga che non è mai esistita dal punto di vista logico.
<Quindi due transazioni possono agire contemporaniamente su uno stesso
record.
2- costruzione di Letture non ripetibili: />
Lettura non ripetibile
Situazione in cui una transazione legge la stessa riga più volte e tra una
lettura e l'altra una transazione diversa modifica tale riga. Poiché la riga
è stata modificata tra le varie letture all'interno della stessa
transazione, ogni lettura restituisce valori diversi e pertanto verranno
introdotte inconsistenze.
< Anche quì mi sembra che due o più transazioni possono agire
contemporaniamente su uno stesso record. />
Ave
giuseppeD
----------------------------------
La tecnica passa, la cultura resta.

 ha scritto nel messaggio
news:bki6vt$207tf$1...@ID-174464.news.uni-berlin.de...

parlero' prettamente di SQL Server che mi vanto di presumere di conoscere un
po'...=:-))   < ed aggiungo che ognuno ha diritto alla propria ignoranza
=;-))))  >
al di la' di quanto gia' esposto da Giuseppe riguardo i livelli di
isolamento, che permettono la definizione del Transaction Processing
mantenendo e rispettando le regole ACID, l'architettura interna di SQL
Server si basa su un modello come ti vado a brevemente a riepilogare.
SQL Server utilizza una architettura multithreaded a singolo processo
conosciuta come Symmetric Server Architecture, con la quale un solo
indirizzo di memoria e' pubblicato, eliminando l'overhead di manutenere
memoria condivisa.
Diversamente, i DBMS tradizionalmente basati su kernel UNIX sono strutturati
in uno dei 2 modi di seguito:
- un primo tipo di architettura utilizza  molteplici porcessi (shadow
process), con un processo per ogni utente, che rende il sistema molto
resource-intensive.
- il secondo modello utilizza un singolo processo che simula una specie di
multi-threading gestendo un round-robin e muovendo le varie richieste ,
gestendo uno stack interno per ogni richiesta ed effettuando un sitch ogni
volta che la particolare richiesta viene eseguita.
Il primo metodo, basato su diversi indirizzi di memoria, deve per forza di
cose basarsi su memoria condivisa per comunicare con gli altri in
esecuzione, ma la memoria condivisa risulta meno efficiente della memoria
privata di processo a seguito dell'overhead necessario per i meccanismi di
sincronizzazione (semafori, mutex, etc.) al fine di evitare collisioni
nell'accedere la memoria condivisa, oltre alle evidenti penalizzazioni
derivanti dai task switching ed accesso sincronizzato.
Nel secondo metodo, chiamato anche "simulated multithreading", molte di
queste complessita' sono demandate direttamente al sistema operativo stesso,
ed i vari processi devono essere "fidati" e "produrre", avanzare, in modo
che anche gli altri processi possano a loro volta essere eseguiti... se tale
fiducia viene meno e l'esecuzione non avanza (errore fatale nel codice,
hardware failure), tutti gli altri task ne possono risentire pesantemente.
SQL Server usa una schedulazione che per certi aspetti si pone tra i due
approcci tradizionali, e puo' anche utilizzare thread leggeri disponibili in
ambiente WinNT noti come "fibers".
Al fine di ottimizzare le prestazioni, SQL Server si arroga la gestione di
tali fibers/processi, utilizzando uno o piu' thread del SO (chiamati
"threads UMS" o "User Mode Schedule"); al fine di gestire la schedulazione.
SQL Server utilizza un solo thread UMS per CPU, ed ogni fiber/processo resta
associato (eternamente..) ad un singolo UMS, mentre WinNT puo' schedulare
ogni UMS su indifferentemente qualsiasi processore disponibile ed ogni UMS
determina quale fiber/pocesso deve essere eseguito in ogni singola unita' di
tempo processore. SQL Server per cui supporta il multiprocessing a livello
di thread invece che a livello di processo, che permette "preemptive
operation" e load-balancing dinamico tra i vari processori.
SQL Server utilizza sempre threads multipli, anche su sistemi
monoprocessore, e questi vengono creati e distrutti dinamicamente in
dipendenza delle attivita' reali in esecuzione, e solitamente il loro numero
si aggira tra i 16 e 100, dipendentemente dall'attivita' di sistema e dalle
configurazioni.
Un pool di threads si occupa di ognuna delle NET-Libraries correntemente
installate, altri threads gesticono invece ad esempio i chekpoint sui
database, il processo del lazywriter, il log writer, e cosi' di seguito;
similarmente, un altro thread gestisce le manutenzioni ordinarie del server,
quali ad esempio il ridimensionamento (fisico) dei database che hanno
impostato tale proprieta'.
Per le connessioni utente, SQL Server utilizza un pool di trhead/fiber dato
che l'utilizzo di un processo per utente sarebbe troppo dispendioso. Quando
una connessione efettua una richiesta, quest'ultima viene allocata e
posizionata in un "completation queue" e sara' processata dal prossimo
thread disponibile nel worker tread pool; tale coda e' una risorsa del SO
chiamata "IOCompletation port". Qualora non fossero disponibili thread in
"idle" nel worker pool per assolvere la richiesta, SQL Server creera' un
altro thread all'uopo, questo fino al
raggiungimento del valore impostato come massimo, diversamente la richiesta
dovra' aspettare la liberazione di un thread da una richiesta precedente.
Tutto cio', vista la base arhitetturale, viene gestito senza la necessita'
di un Transaction Monitor come invece necessario ad altre architetture.
Ogni thread puo' utilizzare anche piu' processori ed addirittura SQL Server
2000 puo' indirizzare tutti i processori eventualmente disponibili anche per
una singola richiesta, se unica richiesta in esecuzione in caso di query
particolarmente complicata, provvedendo a spezzettare la query in unita' da
eseguire in parallelo su piu' CPU, tutto cio' sempre che ci siano piu'
processori rispetto al numero di connessioni attive. Di piu', tale
spezzettamento dei comandi non avra'  luogo se la query non viene
riconosciuta da SQL Server come particolarmente onerosa.
Sotto un normale schema di pool, ogni thread viene portato avanti fino al
completamento, se un thread causa problemi (page fault) solamente quello
specifico thread sara' bloccato, in attesa di che la nuova pagina di virtual
memory venga allocata e che le operazioni di I/o vengano eseguite).
In caso di problemi veri (access violation, ...), solamente quel thread
verra' terminato.
Questo, senza la presunzione di essere esaustivo, riguarda la concorrenza
sull'hardware stesso..
Riguardo invece la concorrenza sui dati, e' degno di nota che SQL Server,
qualora non fosse presente il modulo (e relativo processo) Lock Manager,
sarebbe indifferente alla concorrenza di utenti su risorse quali i dati
stessi.. E' il Lock Manager che garantisce l'acquisizione, verifica e
rilascio dei Lock.
I lock vengono inseriti in una pseudo tabella chiamata syslockinfo, che non
viene mai fisicamente scritta su disco ma rimane in memoria, e che mantiene
i dati di ogni oggetto per il quale e' stato garantito uno dei vari lock
disponibili, come anche una riga per ogni richiesta di lock sui vari
oggetti.
I vari lock vengono inpostati (se verificati e garantiti) alla prima
connessione che arriva a richiederli.
I tipi di lock dei quali solitamente ci interessiamo sono
- Share Lock, imposto automaticamente al momento di leggere fisicamente i
dati, la cui durata dipende dal livello di isolamento della transazione,
anche se solitamente vengon rilasciati non appena terminata l'operazione di
lettura;
- Exclusive Lock, impostati al momento di effettuare operazioni di DML, che
restano comunque attivi fino al termine della transazione;
- Update Lock, una via di mezzo tra gli Share Lock e gli Exclusive Lock,
tipicamente impostati quando una transazione, prima della modifica dei dati
stessi, necessita di una ricerca della risorsa da modificare: SQL Server, al
momento della ricerca, impone un lock Shared sulle risorse che sta
scandendo, imponendo un Update Lock su quello che invece rientrano nel range
da sottoporre a modifica;
- Intent Lock, che si aggiungono alla tipologia base, che indicano alla
granularita' superiore di lock (pagina per una riga, tabella per una pagina)
l'acquisizione di lock di granularita' maggiore: non e' possibile richiedere
un lock a livello di pagina se un lock incompatibile a livello di riga e'
gia' stato garantito ad altri.
Come sappiamo , SQL Server, dalla versione 7.0, e' in grado di imporre lock
a livello di riga, pagina e tabella, come chiaramente puo' imporne anche a
livello di chiave di indice ovvero gruppi qualificati di chiavi di indici;
sommariamente SQL Server supporta 2 tipi di lock su chiavi, dipendenti dal
livello di isolamento corrente della transazione attiva:
- per i livelli di isolamento Read Committed e Repeatable Read, SQL Server
tenta di acquisire lock sulla chiave, e se lindice e cluster viene cosi'
automaticamente posto un lock sulla riga di dati stessa, diversamente
ancora, per i cosidetti Heap, viene impostato un lock sulla chiave e sulla
riga di dati;
- il livello di isolamento Serializable, al fine di garantire tale
isolamento, SQL Server deve almeno sempre imporre dei Lock su un range di
chiavi e/o righe di dati, in modo di evitare phantom, e cosi' di seguito.
Quello che pero' realmente ci interessa, e' la reale compatibilita' di
questi lock, in quanto solo questa ci permette di garantire determinati
limiti di concorrenza sui dati.
Lock concorrenti compatibili sulla stessa risorsa possono essere acquisiti
da piu' utenti, diversamente blocchi incompatibili vengono sempre e comunque
serializzati con uno status di "WAIT" visibile in syslockinfo.
possiamo riassumere tali compatibilita' in una matrice:
Tipo di Blocco                                   (IS)  (S)  (U)  (IX)  (SIX)
(X)
Intent Shared (IS)                                si      si    si      si
si       no
Shared (S)                                           si      si    si
no    no      no
Update (U)                                          si      si    no    no
no       no
Intent Exclusive (IX)                             si      no  no    si
no       no
Shared with Intent Exclusive (SIX)        si      no  no    no    no
no
Exclusive (X)                                        no     no  no    no
no       no
ci sono poi anche altri tipi di lock come gli Schema Stability (Sch-S),
incompatibili con tutt i tipi di lock ad eccezione degli Schema Modification
(Sch-M), questi ultimi non compatibili con nessun altro tipo di lock, ovvero
i Bulk Update (BU), compatibili solo con altri Bulk Lock (al fine di
consentire ad esempio operazioni BCP parallele) e con gli Schema Stability
lock.
Ancora da ricordare sono i cosidetti Latches, lock di tipo piu' leggero e
meno dispendiosi in termini di risorse, utilizzati internamente per
proteggere ad esempio la struttura nel momento in cui questa viene
ispezionata e/o modificata, ma non per fini transazionali sull'integrita'
dei dati.
Ultimi, restano i cosidetti Compile locks, utilizzati internamente al
momento della compilazione di stored procedure, trigger e funzioni utente
(per SQL Server 2000)
Di default SQL Server tenta di acquisire la piu' alta granularita' di lock,
per cui a livello di riga o chiave, al fine di permettere la piu' alta
concorrenza, ma, qualora SQL Server si accorga che mantenere tale alta
granularita' diventa molto oneroso, avviene un escalation di Lock  verso
l'alto (mai verso il basso), e solitamente cio' avviene quando piu' del 40%
del buffer pool interno viene utilizzato da un singolo processo; cio' non
avvera' comunque mai se l'acquisizione di tale lock e' incompatibile con
lock incompatibili garantiti a livello di piu' alta granularita' ad altri
processi.
tutto cio', ripeto senza presunzione di completezza...
desidero scusarmi con quanti siano arrivati a leggere fino a qui se sono
stato prolisso, ma mi sono infojato e fatto prendere la mano, e raccomando a
chi lo deisderasse, di approfondire con gli scritti di Nostra Signora SQL
Server, Kalen Delaney.
saluti e buona domenica
Andrea Montanari
andre...@virgilio.it
montanar...@virgilio.it
http://www.asql.biz/DbaMgr.shtm
DbaMgr2k ver 0.4.0  -  DbaMgr ver 0.50.0
(my vb6+sql-dmo little try to provide MS MSDE 1.0 and MSDE 2000 a visual
interface)
--------- remove DMO to reply

[*Lupo* = 
LupoOrmaiR...@libero.it
 in
news:bki6vt$207tf$
1...@ID-174464.news.uni-berlin.de
] ha scritto:
...
Grazie a tutti. Rileggerò con attenzione.

Alla faccia della mano ;) Ci puoi scrivere su un libro, anche se
chiaramente chi come te legge SQL Server Magazine, si ritrova un
doppione ;).
Per farla breve, perchč credo che dopo questo pappardellone
il Lupo o altri si siano andati a fare un caffč e similari ...
Il 999 client che sta li, certo non aspetta che la coda dei messaggi
venga esaurita, si tratta semplicemente di giochi interni che sql server
fa al fine di restituire quanto prima le informazioni richieste
compatibilmente
con i lock impostati o dal sistema o dall'utente stesso.
Un caso del tipo ciakmania, dove erano tutte query in lettura, queste
venivano esaurite in n processi senza tanti problemi, ma in un caso
dove client 1 fa una transazione che richiede 1 ora e il client 999
fa un'update alla struttura della tabella che transazione 1 sta modificando,
allora client 999 aspetta per poi fallire se le istruzioni inviate vengono
meno alla precedente (o precedenti operazioni) eseguite - quindi
anche un altro update.
E' un concetto piuttosto complesso ...
Saluti
Andrea Moro