Sehr viel ein Neuling auf DB-Arbeit, also schätzen Sie Ihre Geduld mit einer grundlegenden Frage. Ich führe SQL Server 2014 auf meinem lokalen Computer aus und habe eine kleine Tabelle und eine grundlegende Clientanwendung, mit der ich verschiedene Ansätze testen kann. Ich erhalte , was scheint , während sowohl eine Tabellensperre zu sein INSERT INTO
und UPDATE
Anweisungen. Der Client ist eine ASP.NET-Anwendung mit dem folgenden Code:
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();
Ich führe diesen Code aus, dann aus dem Management Studio, das ich ausführe SELECT * FROM LAYOUTSv2
. In beiden Fällen, in denen der Client-Thread angehalten wurde (dh vor dem Festschreiben / Zurücksetzen), bleibt die SELECT-Abfrage hängen, bis das Festschreiben / Zurücksetzen erfolgt.
Der Tabelle ist das Feld LAYOUTS_key als Primärschlüssel zugewiesen. Im Eigenschaftenfenster wird angezeigt, dass es eindeutig und gruppiert ist, wobei sowohl Seitensperren als auch Zeilensperren zulässig sind. Die Sperren-Eskalationseinstellung für die Tabelle ist Deaktivieren ... Ich habe beide verfügbaren Einstellungen von Tabelle und AUTO ohne Änderungen ausprobiert. Ich habe es versucht SELECT ... WITH (NOLOCK)
und das gibt sofort ein Ergebnis zurück, aber wie hier und an anderen Orten gut gewarnt wird, ist es nicht das, was ich tun sollte. Ich habe versucht, den ROWLOCK
Hinweis auf die INSERT
und UPDATE
-Anweisungen zu setzen, aber nichts hat sich geändert.
Das Verhalten, nach dem ich suche, ist das Folgende: Vor dem Festschreiben von INSERT
lesen Abfragen von anderen Threads alle Zeilen mit Ausnahme derjenigen, die INSERT
bearbeitet werden. UPDATE
Lesen Sie vor dem Festschreiben von Abfragen aus anderen Threads die Startversion der zu bearbeitenden Zeile UPDATE
. Kann ich das auf irgendeine Weise tun? Wenn ich weitere Informationen zur Klärung meines Anwendungsfalls benötige, lassen Sie es mich bitte wissen. Vielen Dank.
newkey
auf " something';DELETE FROM LAYOUTSv2 --
". Ihre Aktualisierung wurde erfolgreich abgeschlossen und die Tabelle anschließend geleert, da der Benutzer die Abfrage durch Einfügen eines Apostrophs manipuliert hat. Normalerweise sieht eine parametrisierte Abfrage wie folgt aus: Danach UDPATE LAYOUTSv2 SET LAYOUTS_enabled_b='-3' WHERE LAYOUTS_key=?
weisen Sie dem ?
(dem Parameter) in Ihrem Code separat Werte zu .
WHERE LAYOUTS_key='" + newkey + "'
ist ein komplettes Nein-Nein aus verschiedenen Gründen, einschließlich SQL-Injection, sollten Sie parametrisierte Abfragen verwenden.