Опираясь на темы, ранее затронутые gbn в этих вопросах
Q1 , Q2 , Q3 , Q4 , а также относительно использования синонимов и повторного создания синонимов для сохранения синонимов, указывающих на живые данные, мне не ясно, как предотвратить «состояние гонки» с помощью
"sp_getapplock после BEGIN TRAN в режиме транзакции и перехватывать / обрабатывать статус возврата по мере необходимости."
Документация MSDN для sp_getapplock немного загадочна для меня. Например, может ли resource_name
быть любой выдуманной строкой? Но более важно то, что если я запускаю один процесс, содержащий вложенные процессы, где первым шагом является построение таблиц, и если они успешны, то следующим важным шагом является DROP
и CREATE
существующих синонимов, как бы я правильно реализовать sp_getapplock?
CREATE PROCEDURE [dbo].[some_old_proc]
AS
SET XACT_ABORT, NOCOUNT ON
DECLARE @nested_build_success varchar(3) = 'No'
DECLARE @starttrancount int
BEGIN TRY
SET @starttrancount = @@TRANCOUNT
IF @starttrancount = 0
BEGIN TRANSACTION
-- fill the tables that the synonyms don't point to yet...
EXEC dbo.nested_proc_1
EXEC dbo.nested_proc_2
EXEC dbo.nested_proc_3
EXEC dbo.nested_proc_4
EXEC dbo.nested_proc_5
IF @starttrancount = 0
BEGIN
COMMIT TRANSACTION
SET @nested_build_success = 'Yes'
END
END TRY
BEGIN CATCH
IF XACT_STATE() <> 0 AND @starttrancount = 0
ROLLBACK TRANSACTION
-- RAISERROR... log error event
END CATCH
IF @nested_build_success = 'Yes'
BEGIN TRAN
-- simple talk article
-- http://www.simple-talk.com/sql/t-sql-programming/developing-modifications-that-survive-concurrency/
DECLARE @ret INT -- does it matter what the resource_name is?
EXEC @ret = sp_getapplock @Resource = 'DoesNameMatterHere', @LockMode = 'Exclusive';
IF @ret < 0
BEGIN
-- log error message?
END
ELSE
BEGIN
-- call the proc that a does a DROP and CREATE of the relevant synonyms
-- so the synonyms point at a different set of tables...
EXEC dbo.change_the_synonyms
END
COMMIT TRAN
Возможно, существует другой и лучший способ избежать состояния гонки, чем использование sp_getapplock, или доступен хороший пример того, что я пытаюсь сделать?