SQL CLR. Имеет ли значение оператор блокировки? - PullRequest
0 голосов
/ 03 марта 2010

Я написал следующий фрагмент кода (хранимая процедура sql clr), который записывает сообщения в локальный файл. Проблема возникает, когда несколько подключений вызывают хранимый процесс одновременно. Поэтому я использовал оператор блокировки. Но это, кажется, не имеет никакого значения? Что я тут не так делаю?

lock (SqlContext.Pipe)
{
    StreamWriter sw = File.AppendText("C:\Date.txt");
    int y = 50;

    while (y != 0)
    {
        sw.WriteLine(DateTime.Now + " " + serverName + " -- " + jobId.ToString() );
        System.Threading.Thread.Sleep(new Random().Next());
        y = y - 1;
    }
    sw.Close();

}

1 Ответ

7 голосов
/ 03 марта 2010
Сам по себе оператор блокировки

ничего не защищает. Магия происходит только тогда, когда все потоки блокируют один и тот же объект . В вашем случае каждый поток блокирует свой собственный канал контекста, поведение будет идентичным с блокировкой или без нее.

Кроме того, из-за всех повреждений, которые процедура CLR может нанести внутри SQL, угон работника SQL для ожидания в Sleep () определенно является главным нарушителем. Я надеюсь, что вы используете его только в экспериментальных целях.

Чтобы достичь того, что вы, вероятно, хотите, т.е. выполнять только одну процедуру в любое время, используйте блокировку приложения: sp_getapplock. Либо оберните вызов процедуры CLR в T-SQL sp_getapplock / sp_releaseapplock, либо выполните sp_getapplock для соединения с контекстом из своего кода CLR (и выполните sp_releaseapplock при выходе).

...