powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Транзакции: закрыть внутри процедуры
15 сообщений из 15, страница 1 из 1
Транзакции: закрыть внутри процедуры
    #39894977
Ролг Хупин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Почему получаю ошибку в таком случае:
процедура открывает транзакцию, вызывает вторую, которая закрывает внутри.
Хотелось сделать так: большая процедура отрабатывает и в конце вызывается такой "чистильщик", которая кроме всего закрывает, если остались открытые

Код: 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.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[ptest]') AND type in (N'P', N'PC'))
BEGIN
EXEC dbo.sp_executesql @statement = N'CREATE PROCEDURE [dbo].[ptest] AS'
END
GRANT EXECUTE on [dbo].[ptest] to public;
GO
ALTER  PROCEDURE [dbo].[ptest]
@parrollback bit = 0
AS
BEGIN
SET NOCOUNT ON
select @@TRANCOUNT as '@@TRANCOUNT:[ptest] '
if @parrollback is not null and @parrollback>0
	if @@TRANCOUNT>0 rollback tran;
END
GO

IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[pcaller]') AND type in (N'P', N'PC'))
BEGIN
EXEC dbo.sp_executesql @statement = N'CREATE PROCEDURE [dbo].[pcaller] AS'
END
GRANT EXECUTE on [dbo].[pcaller] to public;
GO
ALTER  PROCEDURE [dbo].[pcaller]
AS
BEGIN
SET NOCOUNT ON
begin tran
select @@TRANCOUNT as '@@TRANCOUNT: before [ptest]'
exec ptest 1
select @@TRANCOUNT as '@@TRANCOUNT: after [ptest] '
if @@TRANCOUNT>0 rollback tran;
END
GO
-------------

exec pcaller 


IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[ptest]') AND type in (N'P', N'PC'))
	drop proc pcaller
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[ptest]') AND type in (N'P', N'PC'))
	drop proc ptest
...
Рейтинг: 0 / 0
Транзакции: закрыть внутри процедуры
    #39895005
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ролг Хупин,

непонятно - вторая процедура закрывает транзакцию, без её открытия? Почему это происходит?
...
Рейтинг: 0 / 0
Транзакции: закрыть внутри процедуры
    #39895031
Ролг Хупин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владислав Колосов
Ролг Хупин,

непонятно - вторая процедура закрывает транзакцию, без её открытия? Почему это происходит?


она по идее для того и предназначена
в вызывающей процедуре открывается транзакция, что-то делается, может обломаться и вторая проверяет и закрывает, если остались открытые.
Реально вторая процедура вызывается в
begin try
...
-- тут вызвается несколько процедур, одна из которых может выскочить с ошибкой
end try
begin catch
exec ptest,1
end catch
...
Рейтинг: 0 / 0
Транзакции: закрыть внутри процедуры
    #39895032
Ролг Хупин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
и ошибка
Msg 266, Level 16, State 2, Procedure ptest, Line 0 [Batch Start Line 34]
Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 1, current count = 0.

Вопрос: почему нельзя так сделать? во второй процедуре закрыть транзакции, точнее откатить?
...
Рейтинг: 0 / 0
Транзакции: закрыть внутри процедуры
    #39895087
Minamoto
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ролг Хупин,

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

Как пример: http://rusanu.com/2009/06/11/exception-handling-and-nested-transactions/

Вот ответ от человека, который называет себя "Technical Architect working at the Microsoft Technology Center":

https://dba.stackexchange.com/questions/212115/handling-transaction-count-after-execute-indicates-a-mismatching-number-of-begi Performing a ROLLBACK in a stored procedure that didn't start the transaction is also an error, and will generate this message.
...
Рейтинг: 0 / 0
Транзакции: закрыть внутри процедуры
    #39895090
Ролг Хупин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Minamoto
Ролг Хупин,

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

Как пример: http://rusanu.com/2009/06/11/exception-handling-and-nested-transactions/

Вот ответ от человека, который называет себя "Technical Architect working at the Microsoft Technology Center":

https://dba.stackexchange.com/questions/212115/handling-transaction-count-after-execute-indicates-a-mismatching-number-of-begi Performing a ROLLBACK in a stored procedure that didn't start the transaction is also an error, and will generate this message.


про взрыв мозга - согласен, но, скажем, вызывающая процедура вызвает 5 разных, одна из которых генерирует ошибку.
Я вижу в таком случае - на выходе вызывающей остается незакрытая транзакция.
Вот и подумал сделать процедуру типа ptest,
но хотелось бы понять - почему ошибка возникает?
...
Рейтинг: 0 / 0
Транзакции: закрыть внутри процедуры
    #39895097
Фотография Yasha123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ролг Хупин

Я вижу в таком случае - на выходе вызывающей остается незакрытая транзакция.

а не надо такое видеть.
во всех внутренних в catch -- throw
во внешней в catch -- rollback
...
Рейтинг: 0 / 0
Транзакции: закрыть внутри процедуры
    #39895100
Ролг Хупин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Yasha123
Ролг Хупин

Я вижу в таком случае - на выходе вызывающей остается незакрытая транзакция.

а не надо такое видеть.
во всех внутренних в catch -- throw
во внешней в catch -- rollback


так работает, но тяга к знаниям закрутила, хотелось понять.
внутренние процедуры писаны не мной, туда Заратустра не позволяет вмешиваться.
...
Рейтинг: 0 / 0
Транзакции: закрыть внутри процедуры
    #39895128
felix_ff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ролг Хупин,

это поведение by design

описанно в справке по rollback.

можете поиграться:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
create or alter proc usp_test1
as 
begin transaction
go
create or alter proc usp_test2
as
if xact_state() <> 0 rollback transaction
go

select @@TRANCOUNT
exec usp_test1
select @@TRANCOUNT
exec usp_test2
select @@TRANCOUNT



add: хотя на самом деле не совсем точно, потому что в справке написано что "This message does not affect subsequent processing"
а по факту транзакция переходит в uncommitable state
...
Рейтинг: 0 / 0
Транзакции: закрыть внутри процедуры
    #39895179
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ролг Хупин
но хотелось бы понять - почему ошибка возникает?
Потому что МС установил такое правило.
...
Рейтинг: 0 / 0
Транзакции: закрыть внутри процедуры
    #39895196
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Yasha123
Ролг Хупин

Я вижу в таком случае - на выходе вызывающей остается незакрытая транзакция.

а не надо такое видеть.
во всех внутренних в catch -- throw
во внешней в catch -- rollback


Садись - неуд.

Код: sql
1.
set xact_abort on;
...
Рейтинг: 0 / 0
Транзакции: закрыть внутри процедуры
    #39895221
Фотография Yasha123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
set xact_abort on;

begin tran 
   create table dbo.test(id int);
   drop table dbo.nonexistingtable;
commit;

select *
from dbo.test;


что-то нету роллбэка, а xact_abort on есть
...
Рейтинг: 0 / 0
Транзакции: закрыть внутри процедуры
    #39895333
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Yasha123
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
set xact_abort on;

begin tran 
   create table dbo.test(id int);
   drop table dbo.nonexistingtable;
commit;

select *
from dbo.test;


что-то нету роллбэка, а xact_abort on есть


Суслика нет, а он есть.

Фсе работает. Там где надо.
...
Рейтинг: 0 / 0
Транзакции: закрыть внутри процедуры
    #39895425
Фотография Yasha123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
aleks222

Суслика нет, а он есть.

и имя ему алекс-двоечник.
роллбэка правда так и нет в моем примере

aleks222

Фсе работает. Там где надо.

еще бы.
надо в паре с try..catch.
который суслик не захотел признать
...
Рейтинг: 0 / 0
Транзакции: закрыть внутри процедуры
    #39895445
Ролг Хупин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
aleks222
Yasha123
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
set xact_abort on;

begin tran 
   create table dbo.test(id int);
   drop table dbo.nonexistingtable;
commit;

select *
from dbo.test;


что-то нету роллбэка, а xact_abort on есть


Суслика нет, а он есть.

Фсе работает. Там где надо.


в моем примере (см. первый мєсиджь) не работает
...
Рейтинг: 0 / 0
15 сообщений из 15, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Транзакции: закрыть внутри процедуры
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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