альтернатива встроенной скомпилированной хранимой процедуре sp_getapplock

тлдр; какова альтернатива sp_getapplock в собственной скомпилированной хранимой процедуре.

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

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

Я гуглил и не нашел ответа.


person Arjun Vachhani    schedule 14.06.2018    source источник
comment
Если вы разрешаете только одному процессу за раз получать доступ к таблице через хранимую процедуру, не побеждаете ли вы цель использования таблицы, оптимизированной для быстрой памяти? не будет ли тогда это узким местом?   -  person Mitch Wheat    schedule 14.06.2018
comment
@MitchWheat мы используем таблицу, оптимизированную для памяти, только потому, что они быстрее. согласно бизнес-правилу, мы не можем обрабатывать несколько запросов параллельно.   -  person Arjun Vachhani    schedule 14.06.2018
comment
тогда почему бы не сделать это в памяти приложений?   -  person Mitch Wheat    schedule 14.06.2018
comment
@MitchWheat это финансовые данные, я хочу гарантировать надежность транзакции.   -  person Arjun Vachhani    schedule 14.06.2018
comment
вот почему у нас есть lock() !   -  person Mitch Wheat    schedule 14.06.2018
comment
@MitchWheat в памяти приложения, мы можем использовать lock(), но как только мы говорим, что транзакция завершена, она должна быть надежной, даже в случае сбоя машины/приложения.   -  person Arjun Vachhani    schedule 14.06.2018
comment
Давайте продолжим это обсуждение в чате.   -  person Arjun Vachhani    schedule 14.06.2018


Ответы (1)


Один из методов заключается в выполнении sp_getapplock во внешней хранимой процедуре, которая оборачивает вызов собственного процесса:

CREATE PROC dbo.usp_NativeProcWrapper
AS
BEGIN TRY
    BEGIN TRAN;
    EXEC sp_getapplock 'dbo.usp_NativeProc', 'Exclusive', 'Transaction';
    EXEC dbo.usp_NativeProc;
    EXEC sp_releaseapplock 'dbo.usp_NativeProc', 'Transaction';
    COMMIT;
END TRY
BEGIN CATCH
    IF @@TRANCOUNT > 0 ROLLBACK;
    THROW;
END CATCH;
GO
person Dan Guzman    schedule 14.06.2018
comment
Спасибо за обходной путь, любой другой более чистый способ сделать это в хранимой процедуре, скомпилированной в собственном коде. - person Arjun Vachhani; 14.06.2018
comment
Собственные процессы могут выполнять только другие собственные процессы, поэтому просто невозможно выполнить sp_getapplock из собственного процесса напрямую. Этот обходной путь довольно прост и хорош для ваших нужд, ИМХО. Если вас беспокоит производительность, вы можете запускать однопоточные тесты с оболочкой и без нее. Я бы не ожидал, что разница будет настолько существенной. - person Dan Guzman; 14.06.2018