Newsgroup: it.comp.lang.visual-basic
Titolo: Select e transazioni aperte

Ciao.
Ho un programma dove prima di visualizzare un form attivo una transazione
con cn.begintrans.
Il database è SqlServer2000 ma in teoria il software dovrà funzionare anche
con Oracle.
L'utente può eseguire diverse modifiche nel form e poi cliccare su OK (in
questo caso esegui cn.committrans) oppure su Annulla (cn.RollbackTrans).
Fino ad oggi funzionava tutto bene. Ma adesso è arrivato l'immancabile
problema.
Se un altro utente esegue una semplice Select sulle tabelle che in teoria il
primo utente sta modificando, la Select si blocca.
Ho provato a riprodurre il problema con un semplice programma in VB in
questo modo:
Set cn = New ADODB.Connection
cnStr = "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security
Info=False;Initial Catalog=Prova;Data Source=."
cn.ConnectionString = cnStr
cn.Open
cn.BeginTrans
m_IdProva = 4117
cn.Execute "UPDATE Tabella SET IdAnag=Null WHERE Id=" & m_IdProva
cn.RollbackTrans
Se metto un breakpoint sull'ultima riga, quindi c'è una modifica in attesa
di conferma e provo ad eseguire in Query Analyzer una Select tipo "select *
from Tabella", sta lì.. dicendo Esecuzione batch di query in corso, finchè
non torno in VB e termino la transazione.
E' possibile evitare che la Select si blocchi, magari ritornando i valori
dei record com'erano all'inizio della transazione?
Ho provato a impostare la proprietè IsolationLevel a diversi valori, ma non
cambia nulla.
Grazie a tutti.
Ciao
-- 
Skysurfer

E' normale. Si blocca perchè l'apertura di una transazione
implica immancabilmente il lock della tabella che stai
transazionando.
Devi andare a modificare dei parametri a livello di connesione
per la singola sessione o modifiche sull'rdbms per toccare
il comportamento generale del tuo rdbms. Generalmente
la seconda non è una buona cosa, ma dipende da cosa
vuoi fare.
-- 
Saluti
Andrea Moro


Vorrei solo che un altro utente potesse leggere i dati della tabella, anche
se è lockata dalla transazione del primo utente...
Grazie
-- 
Skysurfer

Allora cerca nel BOL (Book on Line) "table locking". Qualche cosa di
utile ti viene fuori sicuramente. Anche se francamente non è che comprenda
il perchè un tizio dovrebbe leggere dati in fase di aggiornamento.
Ma per carità, scelte del programmatore ...
-- 
Saluti
Andrea Moro


Beh... in un programma multiutente non mi sembra così strano che qualcuno
possa interrogare una tabella, mentre qualcunaltro magari sta modificando
dei dati nella stessa tabella.
Comunque ho visto che aprendo il recordset come Dynamic o ForwardOnly, la
Select funziona. Mentre se lo apro con OpenStatic oppure Keyset si blocca e
va in Timeout.
Non ho ben capito il motivo comunque. Mi sarei aspettato piuttosto che
andasse in Timeout con il Dynamic e non con l'OpenStatic....
Grazie.
Ciao
-- 
Skysurfer

 andasse in Timeout con il Dynamic e non con l'OpenStatic....
Il motivo č che dovresti leggere le definizioni dei cursori, sono alquanto
contraddittori rispetto al nome che portano.
Vedrai che leggendo l'help ti si chiariranno n concetti.
-- 
Saluti
Andrea Moro

 temporanea, o una stored procedure o altro o loccaggio dei dati.
Ho il "sospetto fondato" che il buon skysurfer apra la transazione al
momento dell' _inizio editazione_ da parte dell'utente.
Ecco perchč i locking sono cosě lunghi.
Corretto quello, va tutto a posto.
ciao
ugo

 ugo
In realtà è la prima volta che uso le transazioni e le ho usate così:
All'apertura del Form inizio una transazione con BeginTrans
Alla chiusura del Form se l'utente clicca su OK faccio un Commit, se clicca
su Annulla faccio un Rollback.
Nel form possono essere modificati dati di varie tabelle, alcune dal form
stesso, altri in form richiamati dal form principale.
Mi sembra il modo più comodo per permettere all'utente di annullare un
blocco di modifiche.
Tu come faresti?
Ciao
-- 
Skysurfer

 clicca su Annulla faccio un Rollback.
Ribingo ...
Se tu apri la form e apri la transazione stai loccando quei record.
Bene cosa succede se il tizio o la tizia ti vanno in maternità e ti lasciano
il pc acceso loccato da password? Uao ... per nove mesi non leggi
i dati nelle tabelle. Poco allettante come prospettiva.
Le transazioni, così come le connessioni e le aperture ai recordset
vanno tenuti in vita lo stretto necessario.
Nella tua form cosa fai, hai dei dati caricati e li vuoi verificare
on the fly? Poco valido come sistema, ma se è questo quello che vuoi,
lo scotto da pagare è quello che hai riscontrato.
Diversamnete carichi dei dati, li lasci sulla form, arriva il tizio e li
modifica.
Lascia il pc acceso per 10 minuti o 9 mesi, non te ne frega niente.
Solo e se premerà ok o annulla farai qualcosa. Se preme ok dopo 9 mesi
o dopo 10 minuti, prima di andare ad inserire, aggiornare o quello che vuoi
fare, verifichi che la situazione precedente non sia cambiata.
Sul come, se ti cerchi un post vecchio (molto vecchio), spiegavo la tecnica
che utilizzo io 2 da ormai 8 anni.
-- 
Saluti
Andrea Moro

 tecnica che utilizzo io 2 da ormai 8 anni.
Posso dirlo, fuori dai denti?
Vabbè, lo dico. Le transazioni sono il frutto di una mente malata, in
subordine "leggermente fantasiosa" ( non quella di A.M., chiaro, anche se le
usa :-P ). Perchè. Per esempio per i motivi di cui sopra.
Qualcuno mi dica a cosa servono le transazioni, nella realtà. Già, giusto
nella realtà, è l'unica cosa vera in questo mondo teorico.
A fare un rollback? Ok, ma posso affermare che se occorre fare un rollback
c'è qualcosa che non va nell'architettura del database (o nella mente di chi
lo gestisce) oppure è andata via corrente (altra cosa che si deve dare per
scontata, la corrente, intendo...) oppure al database "gli si sono
incrociati i diti"?
E poi, mi si dica per favore, quando un rollback risulta necessario, che
MsgBox esponete all'operatore? Della serie "qualcosa è andato male. Riprova
e sarai più fortunato". Anche considerando il più disponibile/elastico degli
operatori, siete masochisti.
Per me l'unica regola è questa: Mai consentire l'intervento dell'operatore
quando è possibile automatizzare un'operazione. Se la stessa non va a
termine (fermo restando un decente architettura del db, qualche neurone di
chi lo gestisce e, ovviamente, la corrente) è solo colpa della sfiga (no,
non sto scherzando). Quindi via anche il lock pessimistico (quello che
blocca alla variazione), veramente assurdo, quanto l'irrealismo delle
transazioni. Posso dire che, nel suo piccolo, è concettualmente identico?
Se transazionassimo dovremmo anche prevedere un rollback anche per un "ti
va?" "ma-mi-mu".
Ora, se ne siete capaci (e senza usare le mani), rollbackatemi questo
micidiale "ma-mi-mu".
Sempre senza scherzi e assolutamente IT.

 Bingo ...
Il problema è che come dicevo prima dal form posso modificare dati di
diverse tabelle.
Per esempio posso aggiungere una serie di nominativi collegati al contratto
rappresentato dal form principale.
In questo caso aggiungo un record ad una tabella di relazione (che contiene
IdContratto, IdRichiedente) per ogni Richiedente inserito.
E ci sono casi in cui devo aggiungere anche altri record di questo tipo in
altre tabelle.
Come posso fare per annullare tutti questi inserimenti nel caso in cui
l'utente prema Annulla?!?
Grazie e ciao.
-- 
Skysurfer

Sempre senza scherzi e assolutamente IT.
Serissimo pur'io.
-- 
ciao, hal

 anche se le usa :-P ). Perchè. Per esempio per i motivi di cui sopra.
Ehm ... io ho detto quali sono i problemi delle transazioni, non che le
uso. Io uso sp e similari, non transazioni vb con il suo macchinoso
modo di lavorare che non porta ad un fico secco se non problemi.
-- 
Saluti
Andrea Moro

modo di lavorare che non porta ad un fico secco se non problemi.
Riehm... questa me la spieghi... quale sarebbe questo "macchinoso"
modo di lavorare?
-- 
ciao, hal


Scusate... ma alla fine come posso fare per permettere all'utente di
Annullare una serie di modifiche su varie tabelle eseguite da un form, se
non facendo il Rollback di una transazione?
Grazie e ciao
-- 
Skysurfer

 form, se non facendo il Rollback di una transazione?
in generale, evitando di scrivere i dati nel database fino a quando
l'operatore non conferma di voler salvare i dati.
L'implementazione di questa tecnica può essere estremamente banale o
complicata, in funzione della struttura del database.
--
Salutoni
Sergio


Nel caso della mia applicazione non è per niente banale.
Anche perchè ho già scritto parecchio codice che funziona bene (finchè è in
monoutenza, ma me ne sono accorto troppo tardi!!!).
Quello che mi servirebbe è solo poter eseguire una select anche se c'è una
transazione aperta sulla stessa tabella... ma è una cosa così assurda?
Ho provato aggiungendo WITH (NOLOCK) al termine della Select ed in effetti
così funziona ma:
- Non ho voglia di modificare tutti le select che ho già scritto
- Non sono sicuro che sia una clausola standard (nel senso che andrà bene
anche con Oracle)
- Mi chiedo a cosa serve impostare il recordset LockReadOnly se comunque non
riesce a leggere i record della tabella...
Vi prego aiutatemi!!!!
Ciao
-- 
Skysurfer

 Nel caso della mia applicazione non è per niente banale.
la soluzione più complessa (afaik) prevede l'utilizzo dei recordset
disconnessi: carichi i dati che ti servono, ti scolleghi dal db, effettui le
variazioni in locale e successivamente aggiorni il db origine. hai l'ovvia
complicazione che devi controllare se qualcuno ha già aggiornato i record da
te modificati, ma è la soluzione più "completa" (sempre afaik)
--
Salutoni
Sergio

 ha scritto nel messaggio
news:mq9blvo4pit930n2j...@4ax.com...

:)
ciao
ugo

 ha scritto nel messaggio
news:g92alvsb7b38ju2jr...@4ax.com...

[cuttone]
approvo e sottoscrivo tutto...e tiro le orecchie al canide... ;-P
ciao
ugo