[SQL SERVER EXPRESS] Concorrenza e aggiornamento dati

venerdì 04 marzo 2011 - 14.31
Tag Elenco Tags  VB.NET  |  .NET 3.5  |  Windows XP  |  Visual Studio 2008  |  SQL Server 2005

jackk87 Profilo | Junior Member

Buonasera a tutti,
devo sviluppare un'applicazione multiutente e stavo pensando di usare il VB.NET con SQL SERVER EXPRESS.
Le mie domande sono:

1. Come gestisco la concorrenza degli utenti?
2. Come effettuo l'aggiornamento dei dati?


Esempi:

1. Mentre un'utente sta modificando un record un'altro utente lo cancella al momento che il primo utente clicca sul pulsante modifica quel record non esiste più e quindi c'è errore. Per non parlare se avvengono delle modifiche contemporaneamente.
2. Nel programma ci sarà un form per la visualizzazione dei dati del db in un datagridview, se mentre questo form è aperto un'altro utente inserisce,modifica o elimina un record come faccio a saperlo per aggiornare la datagridview?


per il primo punto stavo pensando di aggiungere un campo alla tabella per il blocco del record però se per caso il programma si blocca,il pc si riavvia o si spegne quel record rimarra sempre bloccato.
Vorrei risolvere i 2 punti stramite sql server express visto che è abbastanza potente.
Spero che ognuno di voi esprima la propria opinione tramite esempi link e argomenti da studiare.

grazie a tutti in anticipo

dompa72 Profilo | Senior Member

>Buonasera a tutti,
>devo sviluppare un'applicazione multiutente e stavo pensando
>di usare il VB.NET con SQL SERVER EXPRESS.
>Le mie domande sono:
>
> 1. Come gestisco la concorrenza degli utenti?
> 2. Come effettuo l'aggiornamento dei dati?
>
>
>Esempi:
>
>1. Mentre un'utente sta modificando un record un'altro utente
>lo cancella al momento che il primo utente clicca sul pulsante
>modifica quel record non esiste più e quindi c'è errore. Per
>non parlare se avvengono delle modifiche contemporaneamente.
>2. Nel programma ci sarà un form per la visualizzazione dei dati
>del db in un datagridview, se mentre questo form è aperto un'altro
>utente inserisce,modifica o elimina un record come faccio a saperlo
>per aggiornare la datagridview?
>
>
>per il primo punto stavo pensando di aggiungere un campo alla
>tabella per il blocco del record però se per caso il programma
>si blocca,il pc si riavvia o si spegne quel record rimarra sempre
>bloccato.
>Vorrei risolvere i 2 punti stramite sql server express visto
>che è abbastanza potente.
>Spero che ognuno di voi esprima la propria opinione tramite esempi
>link e argomenti da studiare.
>
>grazie a tutti in anticipo

Per iniziare ti consiglio di utilizzare i livelli di isolamento per Inserimento, Aggiornamento ed cancellazione, penso ad un READCOMMITTED, questo vincola per tutta la transazione i record interessati garantendo la consistenza dei dati. La transazione (possono essere eseguite più query di aggiornamento) può essere confermata solo quando tutta la transazione è andata a buon fine con il Commit altrimenti rollback fa in modo che non ci siano conseguenze sulla consistenza, esempio mentre scrivi i record si verifica una condizione che non permette la continuazione della transazione stessa tipo blocco PC oppure una condizione software.
Naturalmente devi gestire anche la possibilità che un utente diverso dal precedente è interessato a questi dati, io di solito utilizzo il livello SNAPSHOT (questo livello non è presente di default su SQL Server è necessario attivarlo), questo per garantire all'utente di visualizzare i dati corretti in quel momento. Questo è necessario anche per evitare un blocco in attesa delle modifiche da parte di altri utenti.

esempio di codice

System.Data.SqlClient.SqlConnection cn = new System.Data.SqlClient.SqlConnection(stringa di connessione);
cn.Open();
System.Data.SqlClient.SqlTransaction tr = cn.BeginTransaction(IsolationLevel.ReadCommitted);
System.Data.SqlClient.SqlCommand cm = new System.Data.SqlClient.SqlCommand("", cn, tr);
cm.CommandText = "Insert into Tabella1 (IDcampo) values (valore)";
cm.ExecuteNonQuery();

cm.CommandText = "Insert into Tabella2 (IDcampo) values (valore)";
cm.ExecuteNonQuery();

cm.CommandText = "Update Tabella3 set Tabella1_IDcampo = Valore where Tabella1_IDcampo = ValoreTabella2";
long lngRecAffect = cm.ExecuteNonQuery();

if (lngRecAffect == 0)
tr.Rollback //Se l'ultimo update non effettua la conferma dei dati
else
tr.Commit //Altrimenti rende effettive tutte le query

cn.close()

Mentre questo codice era in esecuzione nessun altro utente (tranne il livello ReadUncommitted) può accedere ai dati modificati.

spero di esserti stato d'aiuto

Ciao

jackk87 Profilo | Junior Member

>Per iniziare ti consiglio di utilizzare i livelli di isolamento
>per Inserimento, Aggiornamento ed cancellazione, penso ad un
>READCOMMITTED, questo vincola per tutta la transazione i record
>interessati garantendo la consistenza dei dati. La transazione
>(possono essere eseguite più query di aggiornamento) può essere
>confermata solo quando tutta la transazione è andata a buon fine
>con il Commit altrimenti rollback fa in modo che non ci siano
>conseguenze sulla consistenza, esempio mentre scrivi i record
>si verifica una condizione che non permette la continuazione
>della transazione stessa tipo blocco PC oppure una condizione
>software.
>Naturalmente devi gestire anche la possibilità che un utente
>diverso dal precedente è interessato a questi dati, io di solito
>utilizzo il livello SNAPSHOT (questo livello non è presente di
>default su SQL Server è necessario attivarlo), questo per garantire
>all'utente di visualizzare i dati corretti in quel momento. Questo
>è necessario anche per evitare un blocco in attesa delle modifiche
>da parte di altri utenti.
>
>esempio di codice
>
>System.Data.SqlClient.SqlConnection cn = new System.Data.SqlClient.SqlConnection(stringa
>di connessione);
>cn.Open();
>System.Data.SqlClient.SqlTransaction tr = cn.BeginTransaction(IsolationLevel.ReadCommitted);
>System.Data.SqlClient.SqlCommand cm = new System.Data.SqlClient.SqlCommand("",
>cn, tr);
>cm.CommandText = "Insert into Tabella1 (IDcampo) values (valore)";
>cm.ExecuteNonQuery();
>
>cm.CommandText = "Insert into Tabella2 (IDcampo) values (valore)";
>cm.ExecuteNonQuery();
>
>cm.CommandText = "Update Tabella3 set Tabella1_IDcampo = Valore
>where Tabella1_IDcampo = ValoreTabella2";
>long lngRecAffect = cm.ExecuteNonQuery();
>
>if (lngRecAffect == 0)
>tr.Rollback //Se l'ultimo update non effettua la conferma dei
>dati
>else
>tr.Commit //Altrimenti rende effettive tutte le query
>
>cn.close()
>
>Mentre questo codice era in esecuzione nessun altro utente (tranne
>il livello ReadUncommitted) può accedere ai dati modificati.
>
>spero di esserti stato d'aiuto
>
>Ciao
>
>

sei stato davvero di aiuto mi hai chiarito molte cose soprattutto con la parte di codice.
Ho dato uno sguardo ai livelli di isolamento qui -> http://msdn.microsoft.com/it-it/library/ms378149%28v=sql.90%29.aspx e al livello snapshot qui -> http://msdn.microsoft.com/it-it/library/tcbchxcb.aspx.
Prima di iniziare nello sviluppo dell'applicazione vera e propria vorrei provare con un semplice database con una sola tabella e fare tutte le prove del caso.
Allora vediamo se ho capito bene:
il livello di isolamento ReadCommitted come mi hai detto tu per tutta la durata della transazione blocca il record in modo che se qualche altro utente prova a fare un aggiornamento dello stesso record gli ritorna un rollback e deve attendere la modifica dell'altro utente. Mentre se l'utente che ha iniziato la transazione gli si blocca il computer oppure si spegne automaticamente sql server da un rollback e sblocca i dati bloccati.
Il livello di isolamento Snapshot all'inizio della transazione a differenza del ReadCommitted non blocca i record ma crea un db temporaneo. Durante la transazione di un'utente viene creato un db temporaneo così se un'altro utente tenta di fare l'aggiornamento sullo stesso record non deve aspettare il termine della transazione dell'altro utente ma si può fare l'operazione contemporaneamente in questo modo se il secondo utente effettua l'aggiornamento prima del primo utente al momento che il primo utente va a salvare i dati gli torna un roolback perchè all'inizio della transazione viene salvato lo stato originale del record quindi al momento della conclusione della transazione viene effettuata la verifica.

Se ho capito bene il funzionamento dei due livelli di isolamento a questo punto deve scegliere il programmatore quale strada adottare in base alle proprie esigenze in quanto per me sono tutti e due 2 metodi molto efficienti.

Aspetto una opinione da parte vostra se su quello che ho scritto ho detto solo cavolate oppure è così

grazie ancora per l'aiuto

dompa72 Profilo | Senior Member

>
>sei stato davvero di aiuto mi hai chiarito molte cose soprattutto
>con la parte di codice.
>Ho dato uno sguardo ai livelli di isolamento qui -> http://msdn.microsoft.com/it-it/library/ms378149%28v=sql.90%29.aspx
>e al livello snapshot qui -> http://msdn.microsoft.com/it-it/library/tcbchxcb.aspx.
>Prima di iniziare nello sviluppo dell'applicazione vera e propria
>vorrei provare con un semplice database con una sola tabella
>e fare tutte le prove del caso.
>Allora vediamo se ho capito bene:
>il livello di isolamento ReadCommitted come mi hai detto tu per
>tutta la durata della transazione blocca il record in modo che
>se qualche altro utente prova a fare un aggiornamento dello stesso
>record gli ritorna un rollback e deve attendere la modifica dell'altro
>utente.
Ti consiglio la lettura di questo documento http://msdn.microsoft.com/it-it/library/ms173763.aspx (sconsiglio l'attivazione del livello READ_COMMITTED_SNAPSHOT).
In poche parole READ_Committed effettua le operazioni solo su record "liberi" e non permette ad altri la modifica fino al termine della transazione, se un utente sta effettuando un operazione nessun altro utente con READ_Committed può leggerle fino a quando non è finita la transazione del primo utente.
>Mentre se l'utente che ha iniziato la transazione gli
>si blocca il computer oppure si spegne automaticamente sql server
>da un rollback e sblocca i dati bloccati.
Più o meno funziona così, quindi il READ_COMMITTED va utilizzato per transazioni che non durino molto (piccolo consiglio)
>Il livello di isolamento Snapshot all'inizio della transazione
>a differenza del ReadCommitted non blocca i record ma crea un
>db temporaneo. Durante la transazione di un'utente viene creato
>un db temporaneo così se un'altro utente tenta di fare l'aggiornamento
>sullo stesso record non deve aspettare il termine della transazione
>dell'altro utente ma si può fare l'operazione contemporaneamente
>in questo modo se il secondo utente effettua l'aggiornamento
>prima del primo utente al momento che il primo utente va a salvare
>i dati gli torna un roolback perchè all'inizio della transazione
>viene salvato lo stato originale del record quindi al momento
>della conclusione della transazione viene effettuata la verifica.
Lo SNAPSHOT legge l'ultima versione consistente dei dati, in poche parole se un utente modifica i dati (READ_COMMITED), un altro utente con il livello (SNAPSHOT) legge i record "liberi" prima dell'inizio della transazione READ_COMMITED.
>
>Se ho capito bene il funzionamento dei due livelli di isolamento
>a questo punto deve scegliere il programmatore quale strada adottare
>in base alle proprie esigenze in quanto per me sono tutti e due
>2 metodi molto efficienti.
Il consigli per iniziare ti consiglio se un utente deve modificare dati di utilizzare READ_COMMITED, questo permette di leggere/scrivere i dati modificati dalla transazione stessa, esempio Modificare un campo numeratore e leggerne il contenuto "UPDATE TaballaNumeratori SET RecordNumeratore = RecordNumeratore + 1; Select RecordNumeratore from TaballaNumeratori;" ti permette di leggere il nuovo valore ma se per un motivo la transazione non va a buon fine (rollback) la tabella numeratori non è stata modificata, se un altro utente legge la tabella numeratori con il livello SNAPSHOT troverà sempre il valore iniziale.
Questo per garantire che ogni utente acceda alle informazioni che in quel momento siano valide.
>
>Aspetto una opinione da parte vostra se su quello che ho scritto
>ho detto solo cavolate oppure è così
Purtroppo i livelli di isolamento sono un discorso molto ampio e solo pagando "dazio" con la generazioni di molti problemi diventano comprensibili.
Stesso discorso se parliamo delle relazioni tra tabelle, la loro potenzialità viene apprezzata solo se si seguono delle piccole regole e le applicazioni sono critiche.
>
>grazie ancora per l'aiuto
di nulla, spero di esserti d'aiuto

jackk87 Profilo | Junior Member

dompa sei stato moltissimo di aiuto adesso ho le idee molto più chiare quindi devo passare solo alla pratica e inizierò da domani se ho qualche problema lo posto qui

tutto questo riguarda il primo punto per il secondo quello dell'aggiornamento del datagridview ho googlato un pò e volevo un consiglio posto le varie soluzioni:
1-Utilizzo dei trigger
2-Timer che aggiorna di continuo il datagridview
3-Un servizio windows che tiene traccia delle operazioni effettuate dai vari client

allora per il primo punto ho cercato un pò nella documentazione msdn. In pratica quando si effettua un insert, un update o un delete ci sono i trigger che tengono traccia di queste operazioni però a me servirebbe che a un insert o apdate o delete viene inviato a tutti i client l'aggiornamento per la datagridview inoltre ho letto che i trigger appesantiscono molto le operazioni quindi utilizzari se proprio necessario.In pratica non ho capito niente
Per il secondo punto l'applicazione diventa quasi ingestibile e non sono d'accordo in quanto starei sempre a effettuare query sul db, quindi la scardo subito.
Il terzo punto diventa interessante potrei scrivere un servizio windows che viene installato sul pc dove risiede sql server (quindi il server) e ogni qual volta che un client aggiorna,inserisce o elimina un record lo invia al servizio e il servizio invia a tutti gli altri client il bit per aggiornare la datagridview (se hanno il form aperto). Tutto questo utilizzando il protocollo socket come se fosse una semplice chat.

Adesso vorrei un parere anche se ho capito che i trigger sono un'argomento molto vasto infatti non ho capito come fa sql server tramite questi a inviare qualcosa ai client e anche la terza soluzione non mi sembra male.
Aspetto un consiglio dai più esperti grazie ancora in anticipo

dompa72 Profilo | Senior Member

>dompa sei stato moltissimo di aiuto adesso ho le idee molto più
>chiare quindi devo passare solo alla pratica e inizierò da domani
>se ho qualche problema lo posto qui
>
>tutto questo riguarda il primo punto per il secondo quello dell'aggiornamento
>del datagridview ho googlato un pò e volevo un consiglio posto
>le varie soluzioni:
>1-Utilizzo dei trigger
>2-Timer che aggiorna di continuo il datagridview
>3-Un servizio windows che tiene traccia delle operazioni effettuate
>dai vari client
>
>allora per il primo punto ho cercato un pò nella documentazione
>msdn. In pratica quando si effettua un insert, un update o un
>delete ci sono i trigger che tengono traccia di queste operazioni
>però a me servirebbe che a un insert o apdate o delete viene
>inviato a tutti i client l'aggiornamento per la datagridview
>inoltre ho letto che i trigger appesantiscono molto le operazioni
>quindi utilizzari se proprio necessario.In pratica non ho capito
>niente
>Per il secondo punto l'applicazione diventa quasi ingestibile
>e non sono d'accordo in quanto starei sempre a effettuare query
>sul db, quindi la scardo subito.
>Il terzo punto diventa interessante potrei scrivere un servizio
>windows che viene installato sul pc dove risiede sql server (quindi
>il server) e ogni qual volta che un client aggiorna,inserisce
>o elimina un record lo invia al servizio e il servizio invia
>a tutti gli altri client il bit per aggiornare la datagridview
>(se hanno il form aperto). Tutto questo utilizzando il protocollo
>socket come se fosse una semplice chat.
>
>Adesso vorrei un parere anche se ho capito che i trigger sono
>un'argomento molto vasto infatti non ho capito come fa sql server
>tramite questi a inviare qualcosa ai client e anche la terza
>soluzione non mi sembra male.
>Aspetto un consiglio dai più esperti grazie ancora in anticipo
>

Ho gestito una situazione del genere in modo banale, l'utente quando apre la form si aggiorna la griglia ed non avviene nulla fino a quando non è richiesta dall'utente oppure alla prima connessione per altri motivi.
In questo modo non ci sono timer che effettuano connessioni inutili e si evitano di sviluppare servizi complessi.
Per il servizio di notifiche devi utilizzare SqlNotificationRequest (http://msdn.microsoft.com/it-it/library/t9x04ed2.aspx)

Ciao

jackk87 Profilo | Junior Member

Ciao Dompa sto facendo delle prove pratiche riguardo il READCOMMITED e vorrei capire riguardo la porsione di codice che mi hai postato:

System.Data.SqlClient.SqlConnection cn = new System.Data.SqlClient.SqlConnection(stringa
di connessione);
cn.Open(); //Effettuo la connessione al DB
System.Data.SqlClient.SqlTransaction tr = cn.BeginTransaction(IsolationLevel.ReadCommitted); //Imposto la transazione sul livello READCOMMITTED
System.Data.SqlClient.SqlCommand cm = new System.Data.SqlClient.SqlCommand("",
cn, tr); //Associo la transazione e qui dovrebbe partire il blocco del record

Se i commenti che ho messo riguardo le istruzioni è giusto mi chiedo se io vorrei bloccale il record al momento del caricamento della form di modifica e vorrei concludere la transazione al momento della pressione di un pulsante come dovrei dividere il codice?

jackk87 Profilo | Junior Member

ho provato in questo modo:
dichiarazione generale:
Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

sull'evento load del form carico i dati e inizio la transazione con questo codice:
tbID.Text = DataGridView1.Item(0, DataGridView1.CurrentCell.RowIndex).Value.ToString tbTesto.Text = DataGridView1.Item(1, DataGridView1.CurrentCell.RowIndex).Value.ToString Try sqlcon.Open() Catch ex As Exception MsgBox(ex.Message) Exit Sub End Try tr = sqlcon.BeginTransaction(IsolationLevel.ReadCommitted) cm = New System.Data.SqlClient.SqlCommand("", sqlcon, tr)

al momento che clicco sul pulsante aggiorna eseguo questo codice:
Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

eseguo l'applicazione su due pc differenti ma in rete.Dal PC A apro la form di modifica dove inizia la transazione poi sul PC B lancio un delete o un'aggiornamento sullo stesso record dove è aperta la transazione non avviene nessun errore e mi esegue le operazioni fatte dal PC B.
Dov'è che sbaglio?bisogna abilitare qualche cosa in sql server express 2005?

grazie in anticipo

dompa72 Profilo | Senior Member

>ho provato in questo modo:
>dichiarazione generale:
>
>Dim ConnString As String = "Data Source=192.168.190.128,1135;Network
>Library=DBMSSOCN;Initial Catalog=test;User ID=sa;Password=pippo;"
> Dim sqlcon As New SqlConnection(ConnString)
> Dim tr As SqlClient.SqlTransaction
> Dim cm As SqlClient.SqlCommand
>
>
>sull'evento load del form carico i dati e inizio la transazione
>con questo codice:
>
>tbID.Text = DataGridView1.Item(0, DataGridView1.CurrentCell.RowIndex).Value.ToString
>tbTesto.Text = DataGridView1.Item(1, DataGridView1.CurrentCell.RowIndex).Value.ToString
>
> Try
> sqlcon.Open()
> Catch ex As Exception
> MsgBox(ex.Message)
> Exit Sub
> End Try
>tr = sqlcon.BeginTransaction(IsolationLevel.ReadCommitted)
>
>cm = New System.Data.SqlClient.SqlCommand("", sqlcon, tr)
>
>
>al momento che clicco sul pulsante aggiorna eseguo questo codice:
>
>cm.CommandText = "Update paolo set paolo ='" & tbTesto.Text &
>"' where id = " & tbID.Text
> Dim lngRecAffect As Long = cm.ExecuteNonQuery()

inserisci un punto di interruzione qui di seguito (If (lngRecAffect = 0) Then)

>
> If (lngRecAffect = 0) Then
>tr.Rollback() 'Se l'ultimo update non effettua la conferma dei
>dati
> MsgBox("KO")
> Else
>tr.Commit() 'Altrimenti rende effettive tutte le query
> MsgBox("OK")
> End If
>
> Try
> sqlcon.Close()
> Catch ex As Exception
> MsgBox(ex.Message)
> Exit Sub
> End Try
>
>
>eseguo l'applicazione su due pc differenti ma in rete.Dal PC
>A apro la form di modifica dove inizia la transazione poi sul
>PC B lancio un delete o un'aggiornamento sullo stesso record
>dove è aperta la transazione non avviene nessun errore e mi esegue
>le operazioni fatte dal PC B.
>Dov'è che sbaglio?bisogna abilitare qualche cosa in sql server
>express 2005?

Fino a quando non fai andare avanti l'applicazione quei record (meglio pagina) sono inaccessibili
Quando la transazione esegue il rollback o il commit questa si conclude e i dati sono aggiornati/consistenti
Se chiudi la connessione stai facendo implicitamente un rollback alla transazione.
Un consiglio inserisci tutto nel bottone, questo per evitare spiacevoli "autoblocchi"
>
>grazie in anticipo
di niente

jackk87 Profilo | Junior Member

ciao penso che mi sono espresso male:
io vorrei che il PC A al momento che apre la form di modifica dei dati nella quale ci sono i dati caricati da modificare effettua il blocco di quel record in modo che se il PC B vuole modificare quel record o cancellarlo gli visualizza che deve attendere che finisce l'operazione dell'altro utente, quindi quando il PC A ha finito di scrivere tutti i suoi dati modificati nel form al momento che preme un pulsante viene conclusa la transazione e quindi viene sbloccato il record.
Ho provato tutti i livelli di isolamento e con i punti di interruzione non risolvo perchè quello è solo per la modalità debug c'è un modo per effettuare questo con le transazioni?

grazie ancora e scusa se ti disturbo

dompa72 Profilo | Senior Member

>ciao penso che mi sono espresso male:
>io vorrei che il PC A al momento che apre la form di modifica
>dei dati nella quale ci sono i dati caricati da modificare effettua
>il blocco di quel record in modo che se il PC B vuole modificare
>quel record o cancellarlo gli visualizza che deve attendere che
>finisce l'operazione dell'altro utente, quindi quando il PC A
>ha finito di scrivere tutti i suoi dati modificati nel form al
>momento che preme un pulsante viene conclusa la transazione e
>quindi viene sbloccato il record.
>Ho provato tutti i livelli di isolamento e con i punti di interruzione
>non risolvo perchè quello è solo per la modalità debug c'è un
>modo per effettuare questo con le transazioni?
>
>grazie ancora e scusa se ti disturbo
Ti consiglio di cambiare metodo, in questo modo puoi trovarti nella situazione di un utente per ore con la maschera attiva e nessun altro può accedere ai dai, di default SQLServer blocca le pagine non il singolo record, se attivi quest'ultimo hai sicuramente un appesentimento della database.
Io risolvo in questa in due modi:
1. Con una tabella oppure campo di blocco gestendo naturalmente anche le cadute di sistema.
2. Per le visualizzazioni utilizzo il livello SNAPSHOT e se questi devono modificare i record faccio un controllo che quesi dati siano ancora validi informando l'utente.

Una cosa che ho sempre odiato dell'AS400 è proprio il vincolo dei record, è antipatico un messaggio che ti invorma (con caduta della funzione) che il record è in stato di BLOCCO.

Ciao

jackk87 Profilo | Junior Member

Ciao Dompa,
scusa se ti riscrivo qui ma vorrei una tua opinione:
sto scrivendo un'applicazione client/Server utilizzando le transazioni con livelllo ReadCommitted come mi hai suggerito tu adesso sono arrivato a una parte di programma dove ho una datagridview dove l'utente può solo modificare i dati e utilizzo questo codice per salvare tutte le modifiche in un colpo solo nel DB:
Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

la mia domanda è: Facendo l'update della tabella in questo modo (quindi senza transazioni) se 2 client effettuano la stessa operazione insieme potrei avere problemi di concorrenza?oppure gestisce il tutto l'SqlCommandBuilder?

grazie in anticipo

dompa72 Profilo | Senior Member

>Ciao Dompa,
>scusa se ti riscrivo qui ma vorrei una tua opinione:
>sto scrivendo un'applicazione client/Server utilizzando le transazioni
>con livelllo ReadCommitted come mi hai suggerito tu adesso sono
>arrivato a una parte di programma dove ho una datagridview dove
>l'utente può solo modificare i dati e utilizzo questo codice
>per salvare tutte le modifiche in un colpo solo nel DB:
>
>Private Sub btSalvaPosizioni_Click(ByVal sender As System.Object,
>ByVal e As System.EventArgs) Handles btSalvaPosizioni.Click
>If DS_Posizioni.HasChanges() Then 'Se il DataSet è modificato
> Try
>Using CB As New SqlClient.SqlCommandBuilder(DA_Posizioni)
>DA_Posizioni.UpdateCommand = CB.GetUpdateCommand 'Gestisco l'Update
>DA_Posizioni.Update(DS_Posizioni.Tables(0)) 'Aggiorno il DB
> End Using
>DS_Posizioni.AcceptChanges() 'Accetto il DataSet
> Catch ex As Exception
>MessageBox.Show("Errore: " & ex.Message, "Aggiornamento Posizioni
>Campi nel DB", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
> End Try
>MsgBox("Aggiornamento effettuato con successo!", MsgBoxStyle.Information,
>"Avviso..")
> End If
> End Sub
>
>
>la mia domanda è: Facendo l'update della tabella in questo modo
>(quindi senza transazioni) se 2 client effettuano la stessa operazione
>insieme potrei avere problemi di concorrenza?oppure gestisce
>il tutto l'SqlCommandBuilder?
>
>grazie in anticipo

Se non utilizzi una transazione dichiarata, di default sarà ReadCommitted, quindi troverai il secondo UPDATE, il problema si pone se le modifiche riguardano più tabelle (con e senza vincoli).
Spero di essere stato utile
Non amo molto questo genere di update, preferisco gestirli io con controlli sui dati diretti, questo per evitare di aggiornare dati già aggiornati da altri, naturalmente è più lento (di qualche istante) ma in questo modo ho la sensazione di avere il pieno controllo.
Ciao

jackk87 Profilo | Junior Member

>Se non utilizzi una transazione dichiarata, di default sarà ReadCommitted,
>quindi troverai il secondo UPDATE, il problema si pone se le
>modifiche riguardano più tabelle (con e senza vincoli).
>Spero di essere stato utile
>Non amo molto questo genere di update, preferisco gestirli io
>con controlli sui dati diretti, questo per evitare di aggiornare
>dati già aggiornati da altri, naturalmente è più lento (di qualche
>istante) ma in questo modo ho la sensazione di avere il pieno
>controllo.
>Ciao

Le modifiche riguardano una sola tabella, ho capito perfettamente e grazie ancora di tutto
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2017
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5