Ниже приведен мой код, который открывает транзакцию и вставляет строку в таблицу, между тем я открываю другое соединение и запрашиваю ту же таблицу. Программа зависает в строке (*).Базовый тупик базы данных и уровень изоляции транзакции
//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 LEVEL является ReadCommitted
на моей базе данных. Я ожидал count=0
.
Похоже, что соединение 1 блокирует стол, так что соединение 2 не может его прочитать. Если это так, то почему существует УРОВЕНЬ ИЗОЛЯЦИИ ОПЕРАЦИЙ?
О, я нашел https://msdn.microsoft.com/library/ms173763.aspx. Будет ли «SET READ_COMMITTED_SNAPSHOT ON» решить тупик? – Gqqnbig
@LoveRight это ... не лучший способ зафиксировать тупик. IMO есть 3 * хорошие * способы исправить это: 1) выполнить подсчет по тому же соединению, что и транзакция (это даст вам новый счет); 2) реструктурировать код, чтобы вы * не делали этого * - оставив транзакцию открытой здесь очень плохой запах - но если вам нужно ждать (чтобы получить достоверное значение) - тогда * wait *; 3) если вы * должны * прочитать за замком, используйте нижнюю изоляцию; моментальный снимок может решить это, но по причинам, которые в основном кричат «Я не понимаю, что происходит» - это никогда не бывает хорошо. –
Я просто делаю эксперименты. благодаря – Gqqnbig