Molto un principiante nel lavoro su DB, quindi apprezza la tua pazienza con una domanda di base. Sto eseguendo SQL Server 2014 sul mio computer locale e ho una piccola tabella e un'applicazione client di base con cui testare diversi approcci. Ricevo quello che sembra essere un blocco della tabella durante entrambe INSERT INTO
e le UPDATE
dichiarazioni. Il client è un'applicazione ASP.NET con il seguente codice:
OleDbConnection cn = new OleDbConnection("Provider=SQLNCLI11; server=localhost\\SQLEXPRESS; Database=<my db>; user id=<my uid>; password=<my pwd>");
cn.Open();
OleDbTransaction tn = cn.BeginTransaction();
OleDbCommand cmd = new OleDbCommand("INSERT INTO LAYOUTSv2 (LAYOUTS_name_t, LAYOUTS_enabled_b, LAYOUTS_data_m) VALUES ('name', '-1', 'data')", cn, tn);
cmd.ExecuteNonQuery();
cmd.CommandText = "SELECT SCOPE_IDENTITY()";
int newkey = Decimal.ToInt32((decimal)cmd.ExecuteScalar());
Console.WriteLine("Created index " + newkey);
Thread.Sleep(15000);
tn.Commit();
tn = cn.BeginTransaction();
cmd.CommandText = "UDPATE LAYOUTSv2 SET LAYOUTS_enabled_b='-3' WHERE LAYOUTS_key='" + newkey + "'";
cmd.Transaction = tn;
cmd.ExecuteNonQuery();
Console.WriteLine("updated row");
Thread.Sleep(15000);
tn.Rollback();
cn.Close();
Eseguo questo codice, quindi dallo studio di gestione corro SELECT * FROM LAYOUTSv2
. In entrambi i casi in cui il thread client è in pausa (ovvero prima del commit / rollback) la query SELECT si blocca fino a quando si verifica il commit / rollback.
La tabella ha il campo LAYOUTS_key assegnato come chiave primaria. Nella finestra delle proprietà mostra che è univoco e raggruppato, con blocchi di pagina e blocchi di riga consentiti entrambi. L'impostazione dell'escalation del blocco per la tabella è Disabilita ... Ho provato entrambe le altre impostazioni disponibili di Tabella e AUTO senza modifiche. Ho provato SELECT ... WITH (NOLOCK)
e questo restituisce immediatamente un risultato, ma come è ben avvertito qui e in altri luoghi non è quello che dovrei fare. Ho provato a dare il ROWLOCK
suggerimento su entrambe le dichiarazioni INSERT
e UPDATE
, ma nulla è cambiato.
Il comportamento che sto cercando è questo: prima di eseguire il commit di un INSERT
, le query di altri thread leggono tutte le righe tranne quella che viene modificata INSERT
. Prima di eseguire il commit di una UPDATE
query da altri thread leggere la versione iniziale della riga in fase di modifica UPDATE
. C'è un modo per farlo? Se devo fornire altre informazioni per chiarire il mio caso d'uso, per favore fatemelo sapere. Grazie.
newkey
su " something';DELETE FROM LAYOUTSv2 --
". L'aggiornamento verrà completato correttamente e quindi svuotare la tabella perché l'utente ha manipolato la query inserendo un apostrofo. Normalmente, una query con parametri ha un aspetto simile UDPATE LAYOUTSv2 SET LAYOUTS_enabled_b='-3' WHERE LAYOUTS_key=?
, dopo di che si assegnano separatamente i valori al ?
(parametro) nel codice.
WHERE LAYOUTS_key='" + newkey + "'
è un no-no completo per vari motivi tra cui l'iniezione SQL, è necessario utilizzare query con parametri.