Das folgende ist mein Code, der eine Transaktion öffnet und eine Zeile in die Tabelle einfügt, während ich eine andere Verbindung öffne und die gleiche Tabelle abfrage. Das Programm legt bei Zeile (*) auf.Datenbank-Deadlock und TRANSACTION ISOLATION LEVEL
//TestTable is empty.
using (connection1 == new SqlConnection(OpConsoleLib.std.CONNECTIONSTRING)) {
connection1.Open();
SqlCommand cmd = new SqlCommand("Insert into TestTable values('hello')", connection1);
cmd.Transaction = connection1.BeginTransaction();
cmd.ExecuteNonQuery()
using (SqlConnection connection2 = new SqlConnection(OpConsoleLib.std.CONNECTIONSTRING)) {
connection2.Open();
SqlCommand cmd2 = new SqlCommand("Select count(*) from TestTable where name='hello'", connection2); //(*)
int count=Convert.ToInt32(cmd2.ExecuteScalar());
}
cmd.Transaction.Commit();
}
TRANSACTION ISOLATION LEVEL ist ReadCommitted
auf meiner Datenbank. Ich habe count=0
erwartet.
Es sieht so aus, als ob die Verbindung 1 die Tabelle sperrt, so dass die Verbindung 2 sie nicht lesen kann. Wenn das stimmt, warum gibt es TRANSACTION ISOLATION LEVEL?
Oh, ich https://msdn.microsoft.com/library/ms173763.aspx gefunden. Wird 'SET READ_COMMITTED_SNAPSHOT ON' den Deadlock lösen? – Gqqnbig
@LoveRight das ist ... kein guter Weg, um einen Deadlock zu beheben. IMO gibt es 3 * gute * Möglichkeiten, dies zu beheben: 1) führen Sie die Zählung auf der gleichen Verbindung, wie die Transaktion verwendet wird (das wird Ihnen die neue Anzahl geben); 2) restrukturiere den Code so, dass du * dies nicht tust * - eine Transaktion offen zu lassen ist ein sehr schlechter Geruch - aber wenn du warten musst (um den zuverlässigen Wert zu erhalten) - dann * warte *; 3) Wenn Sie * hinter dem Schloss lesen müssen, verwenden Sie eine niedrigere Isolierung; Snapshot könnte dies lösen, aber aus Gründen, die im Grunde schreien "Ich verstehe nicht, was vor sich geht" - was nie gut ist –
Ich mache nur Experimente. Vielen Dank – Gqqnbig