powered by simpleCommunicator - 2.0.50     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Cчетчик транзакций после выполнения EXECUTE показывает несовпадение числа
4 сообщений из 4, страница 1 из 1
Cчетчик транзакций после выполнения EXECUTE показывает несовпадение числа
    #40101373
Игорь_UUS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ошибка:

Счетчик транзакций после выполнения EXECUTE показывает несовпадение числа инструкций BEGIN и COMMIT. Предыдущее число = 1, текущее число = 0.


Я понимаю почему она происходит, но как её обойти не могу понять...
Суть такая, есть начальная процедура, имеет примерно такой вид:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
BEGIN TRY
  ...
  BEGIN TRANSACTION
  ...
    EXECUTE MyStoredProc
  ...
  COMMIT TRANSACTION
  
END TRY
BEGIN CATCH
  IF @@TRANCOUNT > 0  
	ROLLBACK TRANSACTION
  ....
END CATCH



С хранимке MyStoredProc идёт цепочка вызова хранимок, где-то в недрах этой цепочки происходит ошибка в блоке CATCH, и тут нюанс, нужно в таблицу лога внести ошибку.

Там делается:

Код: sql
1.
2.
3.
4.
5.
IF @@TRANCOUNT > 0  
	ROLLBACK TRANSACTION

  -- И далее пишем лог
  INSERT INTO TableLog ...



По выходу из процедуры возникает ошибка, которую написал выше.

Тут вопрос, или как обойти? Или как записать в таблицу лог ошибки?, так чтоб он не откатился с вызовом ROLLBACK TRANSACTION в первичной хранимке.
...
Рейтинг: 0 / 0
Cчетчик транзакций после выполнения EXECUTE показывает несовпадение числа
    #40101427
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Игорь_UUS,

Код: sql
1.
2.
-- И далее пишем лог
-- И далее выбрасываем исключение



Попробуйте использовать такой упрощённый шаблон для обработки ошибок:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
CREATE PROCEDURE [schema].[name]
@param1 int -- внести описание параметра
AS
BEGIN

SET NOCOUNT ON;
BEGIN TRY
	DECLARE @trancnt int = @@trancount;
	-- Не забываем транзакцию открывать, если требуется!
	/*Написать код процедуры*/

END TRY
BEGIN CATCH
	IF @trancnt = 0 AND @@tranCount > 0
		ROLLBACK;
	DECLARE @errorText VARCHAR(4000) = ERROR_MESSAGE(),
			@state TINYINT = ERROR_STATE(),
			@errorNumber BIGINT = ERROR_NUMBER();

	IF (@errorNumber < 50000 
		OR @state = 255) -- Для системной ошибки показать цепочку вызова процедур, @State=255 признак системной ошибки
	BEGIN
		SET @errorText = CONCAT(@errorText, ' ПРОЦ:', ERROR_PROCEDURE(), ', СТРК:', ERROR_LINE(), '; ');
		SET @state = 255;
		SET @errorNumber = 50000;
	END;
	THROW @errorNumber, @errorText, @state;
END CATCH

END



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

Для решения задачи с записью в журнал ошибок можно воспользоваться уведомлением о событиях.
https://docs.microsoft.com/ru-ru/sql/relational-databases/service-broker/event-notifications?view=sql-server-ver15
Уведомления работают независимо от состояния транзакции.
...
Рейтинг: 0 / 0
Cчетчик транзакций после выполнения EXECUTE показывает несовпадение числа
    #40101451
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Игорь_UUS
как обойти?
Никак. Транзакцию надо откатывать в "начальной" процедуре.
Игорь_UUS
как записать в таблицу лог ошибки?, так чтоб он не откатился с вызовом ROLLBACK TRANSACTION в первичной хранимке.
Самое простое - оформить запись в лог процедурой и вызывать ее через self-linked server с отключенной опцией remote proc transaction promotion.
...
Рейтинг: 0 / 0
Cчетчик транзакций после выполнения EXECUTE показывает несовпадение числа
    #40101513
Ролг Хупин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invm
Игорь_UUS
как обойти?
Никак. Транзакцию надо откатывать в "начальной" процедуре.
Игорь_UUS
как записать в таблицу лог ошибки?, так чтоб он не откатился с вызовом ROLLBACK TRANSACTION в первичной хранимке.
Самое простое - оформить запись в лог процедурой и вызывать ее через self-linked server с отключенной опцией remote proc transaction promotion.


в некоторых случаях лог можно писать так:
1. сначала в @ таблицу, а после коммита/роллбэка писать в лог таблицу
2. сбрасывать логи в брокер, там ловить и писать тоже мимо транзакций
...
Рейтинг: 0 / 0
4 сообщений из 4, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Cчетчик транзакций после выполнения EXECUTE показывает несовпадение числа
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]