Таблица медленных транзакций SQL - PullRequest
1 голос
/ 04 августа 2011

У меня очень медленная транзакция sql, которая вставляет новые строки в таблицу.Все остальные запросы «select» из других соединений ожидают, пока этот переход разблокирует таблицу.

Возможно ли получить старые строки из таблицы, пока работает первая транзакция?

SqlExpress 2008 R2.Например:

    private void button1_Click(object sender, EventArgs e)
    {
        System.Threading.Thread t = new System.Threading.Thread(
            delegate()
            {
                var conn = new SqlConnection(@"Data Source=ARTNB\SQLEXPRESS;Initial Catalog=test;User ID=**;Password=******");
                conn.Open();
                var cmd = conn.CreateCommand();
                var tr = conn.BeginTransaction( IsolationLevel.RepeatableRead, "test");
                cmd.Transaction = tr;
                cmd.CommandText = @"INSERT INTO Cards (SerialNumber,OperationID,TariffID,RequestTime,State,AgentInfo) VALUES('1213','345',13, GETDATE(),1,'')";
                cmd.ExecuteNonQuery();
                //very slow transaction
                System.Threading.Thread.Sleep(300000);
                tr.Commit();
                conn.Close();
            });
        t.Start();
    }

    private void button2_Click(object sender, EventArgs e)
    {
        var conn = new SqlConnection(@"Data Source=ARTNB\SQLEXPRESS;Initial Catalog=test;User ID=**;Password=******");
        conn.Open();
        var cmd = conn.CreateCommand();
        var tr = conn.BeginTransaction(IsolationLevel.RepeatableRead, "test2");
        cmd.Transaction = tr;
        cmd.CommandText = @"SELECT COUNT(*) FROM Cards";
        var r = cmd.ExecuteReader();
        r.Read();
        r.Close();
        tr.Commit();
        conn.Close();
    }

Метод button2_Click не извлекает строку сразу, он ожидает коммита в очень медленной транзакции sql, которая вставляет новые строки в таблицу.Все остальные запросы «select» из других соединений ожидают, пока этот переход разблокирует таблицу.

Можно ли извлечь старые строки из таблицы, пока работает первая транзакция?

SqlExpress 2008 R2.Например:

    private void button1_Click(object sender, EventArgs e)
    {
        System.Threading.Thread t = new System.Threading.Thread(
            delegate()
            {
                var conn = new SqlConnection(@"Data Source=ARTNB\SQLEXPRESS;Initial Catalog=test;User ID=**;Password=******");
                conn.Open();
                var cmd = conn.CreateCommand();
                var tr = conn.BeginTransaction( IsolationLevel.RepeatableRead, "test");
                cmd.Transaction = tr;
                cmd.CommandText = @"INSERT INTO Cards (SerialNumber,OperationID,TariffID,RequestTime,State,AgentInfo) VALUES('1213','345',13, GETDATE(),1,'')";
                cmd.ExecuteNonQuery();
                //very slow transaction
                System.Threading.Thread.Sleep(300000);
                tr.Commit();
                conn.Close();
            });
        t.Start();
    }

    private void button2_Click(object sender, EventArgs e)
    {
        var conn = new SqlConnection(@"Data Source=ARTNB\SQLEXPRESS;Initial Catalog=test;User ID=**;Password=******");
        conn.Open();
        var cmd = conn.CreateCommand();
        var tr = conn.BeginTransaction(IsolationLevel.RepeatableRead, "test2");
        cmd.Transaction = tr;
        cmd.CommandText = @"SELECT COUNT(*) FROM Cards";
        var r = cmd.ExecuteReader();
        r.Read();
        r.Close();
        tr.Commit();
        conn.Close();
    }

Метод button2_Click не извлекает строку сразу, он ожидает фиксации в потоке button1_Click.

1 Ответ

4 голосов
/ 04 августа 2011

Одна быстрая карта «из тюрьмы» включает моментальный моментальный снимок для чтения в базе данных, см. Выбор уровней изоляции на основе управления версиями строк , также упоминаемых в Deadlocked! .Когда RCSI включен в базе данных, ваш щелчок «butonn2» будет читать именно то, что вы хотите: он будет читать старую версию строки, без ожидания подтверждения кнопки 1.

Комуenable RCSI, просто запустите это один раз:

ALTER DATABASE [test]  SET READ_COMMITTED_SNAPSHOT ON;

Конечно, бесплатного ланча не существует: включение управления версиями строк повлечет за собой затраты в IO и размере tempdb.См. Использование ресурсов управления версиями строк .Для экземпляра Express не будет ощутимого воздействия.

...