Вызывает ли sp_getapplock проблемы с производительностью SQL Server? - PullRequest
0 голосов
/ 25 апреля 2018

У меня есть хранимая процедура, которая не может быть выполнена одновременно.Несколько процессов вызывают эту хранимую процедуру, но жизненно важно, чтобы процессы обращались к хранимой процедуре последовательно.

Хранимая процедура в основном сканирует таблицу на предмет первичного ключа, который удовлетворяет различным условиям, помечает запись какиспользуется вызывающим процессом, а затем передает первичный ключ обратно вызывающему процессу.

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

Я решил предотвратить параллелизм, используя sp_GetAppLock внутри хранимой процедуры.Я получаю эксклюзивную блокировку транзакции с @Resource, установленным на строку, которая используется только внутри этой хранимой процедуры.Единственной вещью, которая когда-либо блокируется этой блокировкой, является выполнение этой хранимой процедуры.

Вызов внутри хранимой процедуры выглядит следующим образом:

     sp_getapplock @Resource='My Unique String Here' 
         ,@LockMode='Exclusive'  -- Type of lock
         ,@LockOwner='Transaction' -- Transaction or Session
         ,@LockTimeout = 5000

Он работает плавно.Если запущены дюжины экземпляров моего процесса, только один из них выполняет хранимую процедуру в любой момент времени, в то время как остальные 11 послушно стоят в очереди и ждут своей очереди.

Единственная проблема - это наш администратор БД.Он очень хороший администратор баз данных, который постоянно отслеживает блокировку базы данных и получает предупреждение, когда она превышает определенный порог.Мое использование sp_getapplock вызывает много предупреждений.Мой администратор БД утверждает, что блокирование само по себе является проблемой производительности.

Является ли его утверждение точным?Я чувствую, что это «хорошая» блокировка, в которой единственное, что блокируется, - это выполнение хранимой процедуры, и я хочу , чтобы ее заблокировали.Но мой администратор БД говорит, что принуждение SQL Server к принудительному блокированию приводит к значительному сокращению ресурсов.

Могу ли я сказать ему «подавить взломанный канал», как мы привыкли говорить?Или я должен переписать свое приложение, чтобы избежать необходимости sp_getapplock?

Статья, которую я прочитал и продала мне sp_getapplock, находится здесь: sp_getapplock

Ответы [ 2 ]

0 голосов
/ 18 октября 2018

" Хранимая процедура в основном сканирует таблицу на предмет первичного ключа, который удовлетворяет различным условиям, помечает запись как используемую вызывающим процессом, а затем передает первичный ключ обратно вызывающему процессу. "Вот другой способ сделать это внутри SP:

BEGIN TRANSACTION
 SELECT x.PKCol
   FROM dbo.[myTable] x WITH (FASTFIRSTROW XLOCK ROWLOCK READPAST)
  WHERE x.col1 = @col1...

 IF @@ROWCOUNT > 0 BEGIN
    UPDATE dbo.[myTable]
       SET ...
     WHERE x.col1 = @col1
 END

COMMIT TRANSACTION

XLOCK Указывает, что эксклюзивные блокировки должны быть приняты и удерживаться до завершения транзакции.Если указано с помощью ROWLOCK, PAGLOCK или TABLOCK, эксклюзивные блокировки применяются к соответствующему уровню детализации.

0 голосов
/ 25 апреля 2018

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

Позвольте мне объяснить, как:

  1. Proc вызывается, SQL Server назначает ему рабочий поток из пула потоков и начинает выполнение.

  2. Идет вызов 2,3,4, ... снова SQL Server назначает рабочие потоки этим вызовам, потоки начинают выполняться, но из-за полученных вами эксклюзивных блокировок всепотоки приостанавливаются и помещаются в "Waiting List", чтобы ресурсы стали доступными.

  3. Рабочие потоки, число которых на любом сервере SQL Server очень ограничено, задерживаются из-за вашего процесса.

  4. Теперь SQL Server накапливает ожидания из-за того, что разработчик решил сделать.

Как администратор БД, мы хотим, чтобы вы пришли на SQL Server, получили то, что вам нужно, и оставили его как можно скорее.Если вы намеренно оставаетесь там и держитесь за ресурсы и оказываете давление на SQL Server, это разозлит АБД.

Я думаю, вам нужно пересмотреть дизайн своего приложения и найти альтернативное решение.

Возможно, это «Таблица процессов» в SQL Server, обновите ее до некоторого значения при запуске процесса и для каждого вызова сначала проверяйте таблицу процессов, прежде чем запускать следующий вызов для этого процесса.Таким образом, ожидание происходит на уровне приложения, и только когда ресурсы доступны, они переходят в БД

...