Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Проблема с rollback MS SQL server 2000  [new]
maldalik
Member

Откуда:
Сообщений: 63
В общем проблема такого плана, я проверяю на ошибки а потом если они произошли проверяю transactioncount и откатываю но получаю следующую ошибку:
Transaction count after EXECUTE indicates that a COMMIT or ROLLBACK TRANSACTION statement is missing. Previous count = 1, current count = 0.
Причем происходит это если закомментарить строку ниже,
-- exec @ReturnCode = master..xp_cmdshell @Command, NO_OUTPUT
причем в процедурах которые исполнялись раньше без проблем, причем закомментаришь процедуру 3, ошибка выходит выше в процедуре 2 и т.д.. причем там везде свой begin tarn/commit
если эту строку раскомментировать то все ок. Весь мозг поломал.

а весь код примерно такой

Begin
Begin tran
вызов хран_прос_1
вызов хран_прос_2
вызов хран_прос_3

exec @ReturnCode = master..xp_cmdshell @Command, NO_OUTPUT

if isnull(@ReturnCode,10) <> 0
begin
if (@@error!=0) or (0=1)
begin
select @Error_tran = 1
IF @@TRANCOUNT > 0 rollback tran
goto finish
end

end
IF @@TRANCOUNT > 0
begin
commit
end

end
9 ноя 12, 09:06    [13443807]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с rollback MS SQL server 2000  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
https://www.sql.ru/forum/afsearch.aspx?s=Transaction+count+after+EXECUTE+indicates+that+a+COMMIT+or+ROLLBACK+TRANSACTION+statement+is+missing&submit=%CD%E0%E9%F2%E8&bid=1
9 ноя 12, 09:23    [13443888]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с rollback MS SQL server 2000  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 32174
maldalik
причем там везде свой begin tarn/commit
Из за этого и ошибка - "Transaction count after EXECUTE indicates that a COMMIT or ROLLBACK TRANSACTION statement is missing. Previous count = 1, current count = 0." появляется если с состояние транзакции изменилось после вызова процедуры.
9 ноя 12, 09:27    [13443925]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с rollback MS SQL server 2000  [new]
maldalik
Member

Откуда:
Сообщений: 63
alexeyvg,

Не понимаю.
Если в процедуре пошел свой begin tran то по идее @@Rowcount должен измениться на+1 при заходе в процедуру и на -1 после commit/rolback.
Что кстати и подтверждают команды print cast(@@TRANCOUNT as varchar)
введенные до и после запуска внутренних хранимок, они выдают 2 в обоих случаях,
даже после этой ошибки


Кроме того если не комментарить вызов XP_shell то все работает без проблем,
9 ноя 12, 09:47    [13444030]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с rollback MS SQL server 2000  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Rollback изменяет @@TRANCOUNT до 0.
9 ноя 12, 09:48    [13444035]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с rollback MS SQL server 2000  [new]
анонимуз
Guest
maldalik
alexeyvg,
+1 при заходе в процедуру и на -1 после commit/rolback

Заблужаетесь
9 ноя 12, 09:49    [13444049]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с rollback MS SQL server 2000  [new]
maldalik
Member

Откуда:
Сообщений: 63
Гавриленко Сергей Алексеевич,
Ок, откатили все через rolback, но тогда почему не проходит проверка на @@Trancount.
И почему принт показывает после ошибки @@Trancount=2
9 ноя 12, 09:53    [13444078]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с rollback MS SQL server 2000  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 32174
maldalik
Ок, откатили все через rolback, но тогда почему не проходит проверка на @@Trancount.
Почему не проходит - не знаю, но к ошибке это не имеет отношения.

Сиквел требует, что бы до и после вызова ХП уровень транзакции был один и тот же.
maldalik
И почему принт показывает после ошибки @@Trancount=2
То есть до и после вызова процедуры @@Trancount одинаковый, но сиквел пишет ошибку, что не одинаковый? Что то не верится.

Вы лучьше выкладывайте оригинальный код, а не приблизительный, и в теге SRC, а то читать трудно.
Ваш приблизительный код содержить синтаксические ошибки, и вообще выполняться не будет, а строка if (@@error!=0) or (0=1) всегда истинна, независимо от наличия ошибок выполнения.
9 ноя 12, 10:25    [13444307]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с rollback MS SQL server 2000  [new]
maldalik
Member

Откуда:
Сообщений: 63
alexeyvg,

Проблема в том что весь код весьма объемен. Может конечно принты выскакивают не в порядке исполнения но картинка именно такова что trancount =2 до и после ошибки.

И понять же непонятно почему ошибка начинает проявляется после комментирования запуска XP_cmdshell

P.S. И снова не понял почему if (@@error!=0) or (0=1) всегда истина? Ведь 0=1 это False???
И да, код писал не я, мне это разгребать.
9 ноя 12, 10:33    [13444359]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с rollback MS SQL server 2000  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 32174
maldalik
P.S. И снова не понял почему if (@@error!=0) or (0=1) всегда истина? Ведь 0=1 это False???
Потому что @@error всегда равен 0
Ведь это ошибка после выполнения последнего оператора, а последний оператор у вас "if isnull(@ReturnCode,10) <> 0"


maldalik
Может конечно принты выскакивают не в порядке исполнения но картинка именно такова что trancount =2 до и после ошибки.
Нет, принты выскакивают в порядке исполнения.

Т.е. у вас в SSMS такое:
print @@trancount
exec proc
print @@trancount
Вывод:
2
Transaction count after EXECUTE indicates that a COMMIT or ROLLBACK TRANSACTION statement is missing. Previous count = 1, current count = 0.
2
?
Скопируйте сюда весь вывод, может, у вас ошибка внутри вызываемой процедуры...
9 ноя 12, 10:51    [13444465]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с rollback MS SQL server 2000  [new]
maldalik
Member

Откуда:
Сообщений: 63
alexeyvg,

2
Server: Msg 266, Level 16, State 2, Procedure hag_change_tp_create_new, Line 65535
Transaction count after EXECUTE indicates that a COMMIT or ROLLBACK TRANSACTION statement is missing. Previous count = 1, current count = 0.
2

Код в котором это происходит

	if @Abon_catv<>0
		begin		
			print cast(@@TRANCOUNT as varchar)	
			exec hag_OneTimeEntryIns @Abon_catv,@Date_Start_catv,NULL,11,@PID_catv,@Dop_comm_catv
			print cast(@@TRANCOUNT as varchar)	
			if (@@error!=0) or (0=1) 
			begin
				select @Error_tran = 1
				IF @@TRANCOUNT > 0 rollback tran
				goto finish		
			end
		end

но если этот блок закомментарить то ошибка вылетает выше
9 ноя 12, 12:33    [13445307]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с rollback MS SQL server 2000  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Еще раз. Для тех, ко в танке. @@error содержит ошибку, произошедшую в предыдущем стейтменте. А не десят стейтментов назад. Ваш print cast(@@TRANCOUNT as varchar) его тупо сбивает.

Сообщение было отредактировано: 9 ноя 12, 12:35
9 ноя 12, 12:35    [13445320]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с rollback MS SQL server 2000  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 32174
maldalik, Line 65535 это какая строка в процедуре hag_change_tp_create_new?

Ещё обратите внимание н неправильную обработку ошибок, как писал я и Гавриленко Сергей Алексеевич

Если после метки finish у вас выход, то причина ошибки понятна.
9 ноя 12, 12:54    [13445493]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с rollback MS SQL server 2000  [new]
maldalik
Member

Откуда:
Сообщений: 63
alexeyvg,

в реальности exec hag_OneTimeEntryIns @Abon_catv,@Date_Start_catv,NULL,11,@PID_catv,@Dop_comm_catv
это 562 строка, я подозреваю что счетчик слетает из-за вызова процедуры. Всего в процедуре 640 строк
Ок, переписал код вот так, ситуация не изменилась.

	if @Abon_catv<>0
		begin		
			print cast(@@TRANCOUNT as varchar)	
			exec hag_OneTimeEntryIns @Abon_catv,@Date_Start_catv,NULL,11,@PID_catv,@Dop_comm_catv
			if (@@error!=0) or (0=1) 
			begin
				select @Error_tran = 1
				IF @@TRANCOUNT > 0 rollback tran
				goto finish		
			end
			print cast(@@TRANCOUNT as varchar)	
		end


по поводу метки финиш

finish:
	IF @@TRANCOUNT > 0 rollback tran
9 ноя 12, 13:21    [13445801]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с rollback MS SQL server 2000  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Так. Вы не понимаете, как работает rollback. Он не уменьшает счетчик транзакций на единицу. Он откатывает ВСЮ транзакцию, полностью. И если вы вызвали процедуру в транзакции, а в ней сказали rollback, то все, получите на выходе ошибку из начального поста.
9 ноя 12, 13:28    [13445896]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с rollback MS SQL server 2000  [new]
maldalik
Member

Откуда:
Сообщений: 63
Гавриленко Сергей Алексеевич,

Еще раз, rollback в вызванной процедуре вызывается только если произошла ошибка. да, собственно вот она
ALTER  proc hag_OneTimeEntryIns
     @Qty money
    ,@EntryDate datetime
    ,@DocName BBRIEF
    ,@serviceTypeID  BIDENT
    ,@AccountID BIDENT
    ,@Description BCOMMENT
as
begin
    declare @ID BIDENT
    begin tran
    exec oneTimeEntryAdd
     @ID          = @ID
    ,@EntryDate   = @EntryDate
    ,@Qty         = @Qty
    ,@DocName     = @DocName
    ,@serviceTypeID = @serviceTypeID
    ,@AccountID   = @AccountID
    ,@Description =  @Description
    if (@@error!=0) or (0=1) 
    begin
        exec abort @ErrNo=42999,@ResourceName='res_canNotAddOneTimeEntry'
        rollback tran
        return 42999
    end
    commit tran
--    select @ID ID
end


И мне по прежнему непонтяно почему при тех еже самых исходных данных процедура вся головная процедура отлично работает если не комментировать строку
exec @ReturnCode = master..xp_cmdshell @Command, NO_OUTPUT
которая вызывается ниже этой процедуры.
9 ноя 12, 13:47    [13446120]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с rollback MS SQL server 2000  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Ну нельзя делать rollback в процедуре, если она запущена в транзакции. Хоть ошибка, хоть гномы там зеленые.
9 ноя 12, 13:58    [13446258]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с rollback MS SQL server 2000  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 32174
maldalik
Еще раз, rollback в вызванной процедуре вызывается только если произошла ошибка. да, собственно вот она
Так делать нельзя.

В процедуре нужно определять, вызывается ли она в транзакции.

Если да, то управление транзакциями возложить на вызывающую процедуру (собственно, у вас в вызывающей процедуре и есть это управление)
9 ноя 12, 14:09    [13446375]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с rollback MS SQL server 2000  [new]
maldalik
Member

Откуда:
Сообщений: 63
alexeyvg,

Понятно, спасибо, все это придется переписывать. :(
Жаль...
12 ноя 12, 06:11    [13456531]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с rollback MS SQL server 2000  [new]
maldalik
Member

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

ALTER  proc hag_OneTimeEntryIns
     @Qty money
    ,@EntryDate datetime
    ,@DocName BBRIEF
    ,@serviceTypeID  BIDENT
    ,@AccountID BIDENT
    ,@Description BCOMMENT
as
begin
    declare @ID BIDENT,
			@TranFlag TinyInt

	Set @TranFlag=0
	IF @@TRANCOUNT=0 
			Set @TranFlag=1

	If  @TranFlag=1
	    begin tran    

	exec oneTimeEntryAdd
     @ID          = @ID
    ,@EntryDate   = @EntryDate
    ,@Qty         = @Qty
    ,@DocName     = @DocName
    ,@serviceTypeID = @serviceTypeID
    ,@AccountID   = @AccountID
    ,@Description =  @Description
    
	if (@@error!=0) or (0=1) 
    begin
        exec abort @ErrNo=42999,@ResourceName='res_canNotAddOneTimeEntry'

		If  @TranFlag=1
	        rollback tran

        return 42999
    end

	If  @TranFlag=1   
	 commit tran
--    select @ID ID
end
12 ноя 12, 07:57    [13456600]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с rollback MS SQL server 2000  [new]
invm
Member

Откуда: Москва
Сообщений: 9913
maldalik
	if (@@error!=0) or (0=1) 
    begin
        exec abort @ErrNo=42999,@ResourceName='res_canNotAddOneTimeEntry'

		If  @TranFlag=1
	        rollback tran

        return 42999
    end
В чем высший смысл выделенного предиката?
+ Ну и пример для особо упертых
use tempdb;
go
create procedure dbo.spTest
as
begin
 declare @a int;
 
 select @a = 1 / 0;
 
 return 0;
end;
go

exec dbo.spTest;
select @@error;
go

drop procedure dbo.spTest;
go
ЗЫ: Смотреть в сторону try/catch.
12 ноя 12, 09:53    [13456875]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с rollback MS SQL server 2000  [new]
maldalik
Member

Откуда:
Сообщений: 63
invm,

автор
В чем высший смысл выделенного предиката?


А хбз, говорю же код не мой. Я сам в недоумении,
но пока ничего не трогаю пока не пойму как оно работает.
Я вообще с MSSQL c 2004 года не работал, на Oracle был.
Твой пример мне понятен, но зачем ты его привел не понял.
Обработка в вызываемой процедуре верна,
или так тоже не прокатит, и надо писать копию процедуры без транзакции?
12 ноя 12, 10:27    [13457045]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с rollback MS SQL server 2000  [new]
maldalik
Member

Откуда:
Сообщений: 63
invm,

автор
Смотреть в сторону try/catch.

А что в 2000 сервере оно есть?
12 ноя 12, 10:28    [13457052]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с rollback MS SQL server 2000  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 32174
maldalik
вот такой подход к управлению транзакциями корректен в этом случае?
Да, корректен.


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

Нужно контролировать ошибки возвратом какого нибуть кода.
12 ноя 12, 10:47    [13457149]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с rollback MS SQL server 2000  [new]
invm
Member

Откуда: Москва
Сообщений: 9913
maldalik
Твой пример мне понятен, но зачем ты его привел не понял.
Неужели до сих пор не понятно, что обработчик ошибки выполнится только если в вызываемой процедуре не используется return и ошибка произойдет при выполнении последней ее инструкции?
maldalik
А что в 2000 сервере оно есть?
Нету. Тогда надо использовать коды возврата, но никак не анализ @@error после вызова процедуры.
12 ноя 12, 10:49    [13457161]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить