|

CURSORTYPE E LOCKTYPE

Giunti
a questo punto abbiamo ormai imparato a creare la connessione
con il database, a prelevare i dati che ci interessano
e a mostrare a video i risultati selezionati.
Finora abbiamo evitato trattazioni puramente teoriche
in quanto il nostro obiettivo non è quello di
fornire un manuale di ASP, bensì fornire esempi
commentati partendo dai quali si possa comprendere il
funzionamento delle Active Server Pages.
Riteniamo però che possa risultare utile capire
il funzionamento della connessione ai database e il
processo di selezione delle informazioni: in questa
pagina vedremo che cosa si intende per CursorType e
LockType, due argomenti che per la loro natura prettamente
tecnica risultano spesso di difficile comprensione e
per tale motivo ignorati o utilizzati in maniera non
corretta.
Eviteremo comunque di addentrarci in particolari troppo
tecnici, semplificando il più possibile l'argomento
(va bene la teoria, ma non esageriamo!)
(Le informazioni qui presentate sono state rielaborate
partendo dal libro Active Server Pages edizioni Apogeo,
manuale di grande pregio che raccomando vivamente).
Come
stringa di connessione e di selezione dal database xxx.mdb
utilizziamo il seguente codice
|
Dim
Conn
Set Conn = Server.CreateObject("ADODB.Connection")
conn.Open
"driver={Microsoft Access Driver (*.mdb)};dbq="
& server.mappath("xxx.mdb")
Dim RS
Set RS = Server.CreateObject("ADODB.Recordset")
RS.Open "select * from tabella", conn,
3, 3
|
La
connessione ad un database viene spesso paragonata ad
una telefonata: si solleva il ricevitore, viene composto
il numero di telefono, la società telefonica
compie alcune operazioni, il destinatario solleva il
ricevitore e comincia uno scambio di informazioni. In
qualsiasi momento è possibile interrompere il
flusso di dati e chiudere la comunicazione.
Ugualmente per quanto riguarda il database: la prima
cosa da fare è preparare la connessione, ovvero
sollevare il ricevitore. Questa operazione è
eseguita dalla riga
Set
Conn = Server.CreateObject("ADODB.Connection")
Il
passaggio successivo è quello di definire il
database a cui vogliamo collegarci, ovvero il numero
di telefono da chiamare:
conn.Open
"driver={Microsoft Access Driver (*.mdb)};dbq="
& server.mappath("xxx.mdb")
Specifichiamo
infatti di aprire il database xxx.mdb: esistono altri
modi per specificare il database oggetto della connessione,
ma per il momento non ci interessano.
Arrivati a questo punto abbiamo alzato il ricevitore
composto il numero.
A
questo punto ci prepariamo a memorizzare nel recordset
le informazioni che il nostro interlocutore ci fornirà.
Sappiamo che il nostro interlocutore è un database,
al cui interno sono contenute delle tabelle. Le tabelle
sono costituite da colonne chiamate campi e
da righe chiamate record. I campi sono uguali
per tutti mentre nei record sono memorizzate informazioni
di volta in volta diverse.
Un recordset non è altro che un insieme
di record: quando andiamo a selezionare le informazioni
dal database (es. select * from tabella where...
order by...) preleviamo dei record da una tabella:
questi record sono memorizzati nell'oggetto Recorset.
Infatti se dobbiamo mostrare a video il risultato di
una selezione, utilizziamo il comando response.write
rs("campo"), dove rs è appunto
il nostro recordset: i dati sono prelevati dal database,
posizionati nel recordset; quando desidero utilizzarli
vado a prenderli nello stesso recordset.
Per
impostare il recordset è sufficiente scrivere
Dim
RS
Set RS = Server.CreateObject("ADODB.Recordset")
Per
riempire il recordset con i dati prelevati dal database,
utilizziamo il comando Open, ovvero Rs.Open
La
struttura è la seguente:
rs.open
comando, connessione, cursortype, locktype
dove
comando
= "select * from tabella",
ovvero che cosa fare ora che siamo connessi al database.
In questo caso chiediamo di selezionare tutti i campi
di tutti i record
connessione
= è la stringa vista prima che contiene le
informazioni relative alla connessione al database
cursortype
= definisce la modalità di spostamento
all'interno del recordset (non è necessario specificarlo)
locktype
= definisce il tipo di blocco da applicare al database
(non è necessario specificarlo).
CURSORTYPE
A
questo punto i dati sono stati prelevati dal database
e posizionati nel recordset. Abbiamo detto che il recordset
è un insieme di record, all'interno dei quali
possiamo muoverci. Infatti per spostarci al record successivo
utilizziamo il comando rs.movenext
Come opzione predefinita, nel caso in cui non sia
specificato diversamente, è possibile solo spostarsi
in avanti, verso il record successivo: questa è
la soluzione più performante e consigliabile.
Occorre però ricordarsi che non è possibile
spostarsi al record precedente (rs.moveprevious).
Infatti questo tipo di cursore è detto ForwardOnly
(indicato anche con il numero zero).
Fortunatamente non è l'unica opzione disponibile:
ne esistono altre tre, da utilizzare in base alle proprie
esigenze.
- Keyset
(1)
- Dynamic
(2)
- Static
(3)
Ma
è proprio così importante definire il
tipo di cursore?
Immaginiamo di creare una connessione al database e
di definire il comando di selezione: mentre stiamo visualizzando
i dati prelevati dal database, un altro utente mi modifica
un record. Quando arrivo a quel record dovrà
essere visualizzato il nuovo valore o il valore che
era presente al momento in cui ho effettuato il select?
Per esempio chiedo di visualizzare tutti i computer
presenti in catalogo il cui costo sia inferiore ai 1000
euro: immaginiamo che l'addetto alle vendite modifichi
un articolo, cambiando il prezzo da 990 a 1050 euro.
Se il corrispondente record mi viene visualizzato con
il valore di 990, si tratta di un errore: quello non
è il prezzo reale del computer, ma il prezzo
che aveva nel momento in cui ho definito il criterio
di ricerca. Se però mi venisse visualizzato il
prezzo corrente (1050 euro) si tratterebbe comunque
di un errore: infatti il record proposto non corrisponde
al criterio di ricerca impostato.
Il comportamento da tenere viene deciso grazie al tipo
di cursore: il cursore ForwardOnly e il cursore Static
visualizzano il dato non ancora aggiornato; gli altri
due rilevano l'aggiornamento.
Immaginiamo
poi il caso in cui al database venga aggiunto un nuovo
record dopo che io ho effettuato la selezione: questo
record deve essere preso in considerazione oppure no?
L'unico tipo di cursore che rileva questa aggiunta è
quello denominato Dynamic, che però non è
supportato da Access (nel caso creassimo una connessione
ad un database Access impostando questo tipo di cursore,
verrebbe automaticamente utilizzato il cursore Keyset).
Ricapitolando:
Keyset:
sono consentiti i movimenti in entrambe le direzioni.
Inoltre vengono rilevate eventuali modifiche ai dati
avvenute dopo l'apertura del recordset.
Dynamic:
come il cursore precedente. In più è in
grado di aggiornare il recordset con eventuali nuovi
record aggiunti.
Static:
eventuali modifiche ai dati avvenute dopo l'apertura
del recordset non sono rilevate, come anche il cursoer
FowardOnly. A differenza di quest'ultimo però,
consente spostamenti sia in avanti che indietro.
LOCKTYPE
A questo punto si pone un ulteriore problema, ovvero
che cosa fare quando due o più utenti cercano
di modificare o aggiungere un record contemporaneamente.
In questo caso occorre che, all'arrivo del primoutente,
il database venga bloccato rispetto ad altri utenti:
solo quando il primo utente ha terminato il secondo
potrà agire. Anche in questo caso esistono diverse
tipi di blocco:
- ReadOnly
(1)
-
Pessimistic (2)
-
Optimistic (3)
-
BatchOptimistic (4)
Nel
primo caso l'utente accede al database con solo i permessi
di lettura: può leggere i dati presenti ma non
può né modificarli né aggiungerne
di nuovi. Nel caso in cui non sia specificato diversamente,
questa è l'opzione di default.
L'opzione
Pessimistic invece fa sì che, nel momento in
cui il primo utente accede al database, tutti i record
siano bloccati finché non viene eseguito l'aggiornamento
del database stesso. E' il metodo di aggiornamento più
sicuro.
Un
tipo di blocco ottimistico invece blocca i record solo
nel momento n cui viene dato il comando di aggiornamento:
in questo modo anche se mi connetto al database non
blocco l'accesso agli altri utenti. Accesso che viene
invece impedito solo nel momento in cui devo modificare
o aggiungere qualcosa.
Come risulta già dal nome è la soluzione
ottimale, in quanto il database viene bloccato solo
nel momento in cui è realmente necessario, rendendolo
disponibile per altri utenti.
L'ultimo
tipo di bloccaggio consente di modificare più
record prima di eseguire l'aggiornamento: si tratta
comunque di un'opzione ben poco utilizzata.
Sia
per quanto riguarda il cursortype sia per quanto riguarda
il locktype è possibile utilizzare, al posto
dei nomi, i relativi numeri: in questo modo si evitano
eventuali errori dovuti alla trascrizione e si rende
più leggibile il codice.
In
questo caso ricordarsi di includere il file adovbs.inc
nella pagina.
Il file è generalmente posizionato nella cartella
C:\Programmi\File comuni\SYSTEM\ADO. Se non lo avete
a disposizione potete scaricarlo da questo
link
L'inclusione si effettua inserendo, alll'inizio della
pagina la seguente riga
<!--
#INCLUDE FILE="adovbs.inc" -->
Come
si è visto è possibile definire il tipo
di cursore e il tipo di blocco in base alle proprie
esigenze: non è necessario specificarli ogni
volta che ci si connette ad un database. In mancanza
di indicazioni diverse potremo utilizzare solo gli spostamenti
in avanti e accessi al database di tipo 'sola lettura':
opzioni più che sufficienti per la maggior parte
delle operazioni da compiere.
|