Добро пожаловать в форум, Guest >> Войти | Регистрация | Поиск | Правила | | В избранное | Подписаться | ||
Все форумы / Microsoft SQL Server |
![]() ![]() |
Топик располагается на нескольких страницах: [1] 2 вперед Ctrl→ все |
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] Ответить | Цитировать Сообщить модератору |
Гавриленко Сергей Алексеевич Member Откуда: Moscow Сообщений: 37139 |
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] Ответить | Цитировать Сообщить модератору |
alexeyvg Member Откуда: Moscow Сообщений: 31778 |
|
||
9 ноя 12, 09:27 [13443925] Ответить | Цитировать Сообщить модератору |
maldalik Member Откуда: Сообщений: 63 |
alexeyvg, Не понимаю. Если в процедуре пошел свой begin tran то по идее @@Rowcount должен измениться на+1 при заходе в процедуру и на -1 после commit/rolback. Что кстати и подтверждают команды print cast(@@TRANCOUNT as varchar) введенные до и после запуска внутренних хранимок, они выдают 2 в обоих случаях, даже после этой ошибки Кроме того если не комментарить вызов XP_shell то все работает без проблем, |
9 ноя 12, 09:47 [13444030] Ответить | Цитировать Сообщить модератору |
Гавриленко Сергей Алексеевич Member Откуда: Moscow Сообщений: 37139 |
Rollback изменяет @@TRANCOUNT до 0. |
9 ноя 12, 09:48 [13444035] Ответить | Цитировать Сообщить модератору |
анонимуз
Guest |
Заблужаетесь |
||
9 ноя 12, 09:49 [13444049] Ответить | Цитировать Сообщить модератору |
maldalik Member Откуда: Сообщений: 63 |
Гавриленко Сергей Алексеевич, Ок, откатили все через rolback, но тогда почему не проходит проверка на @@Trancount. И почему принт показывает после ошибки @@Trancount=2 |
9 ноя 12, 09:53 [13444078] Ответить | Цитировать Сообщить модератору |
alexeyvg Member Откуда: Moscow Сообщений: 31778 |
Сиквел требует, что бы до и после вызова ХП уровень транзакции был один и тот же.
Вы лучьше выкладывайте оригинальный код, а не приблизительный, и в теге SRC, а то читать трудно. Ваш приблизительный код содержить синтаксические ошибки, и вообще выполняться не будет, а строка if (@@error!=0) or (0=1) всегда истинна, независимо от наличия ошибок выполнения. |
||||
9 ноя 12, 10:25 [13444307] Ответить | Цитировать Сообщить модератору |
maldalik Member Откуда: Сообщений: 63 |
alexeyvg, Проблема в том что весь код весьма объемен. Может конечно принты выскакивают не в порядке исполнения но картинка именно такова что trancount =2 до и после ошибки. И понять же непонятно почему ошибка начинает проявляется после комментирования запуска XP_cmdshell P.S. И снова не понял почему if (@@error!=0) or (0=1) всегда истина? Ведь 0=1 это False??? И да, код писал не я, мне это разгребать. |
9 ноя 12, 10:33 [13444359] Ответить | Цитировать Сообщить модератору |
alexeyvg Member Откуда: Moscow Сообщений: 31778 |
Ведь это ошибка после выполнения последнего оператора, а последний оператор у вас "if isnull(@ReturnCode,10) <> 0"
Т.е. у вас в 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] Ответить | Цитировать Сообщить модератору |
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] Ответить | Цитировать Сообщить модератору |
Гавриленко Сергей Алексеевич Member Откуда: Moscow Сообщений: 37139 |
Еще раз. Для тех, ко в танке. @@error содержит ошибку, произошедшую в предыдущем стейтменте. А не десят стейтментов назад. Ваш print cast(@@TRANCOUNT as varchar) его тупо сбивает.
Сообщение было отредактировано: 9 ноя 12, 12:35 |
9 ноя 12, 12:35 [13445320] Ответить | Цитировать Сообщить модератору |
alexeyvg Member Откуда: Moscow Сообщений: 31778 |
maldalik, Line 65535 это какая строка в процедуре hag_change_tp_create_new? Ещё обратите внимание н неправильную обработку ошибок, как писал я и Гавриленко Сергей Алексеевич Если после метки finish у вас выход, то причина ошибки понятна. |
9 ноя 12, 12:54 [13445493] Ответить | Цитировать Сообщить модератору |
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] Ответить | Цитировать Сообщить модератору |
Гавриленко Сергей Алексеевич Member Откуда: Moscow Сообщений: 37139 |
Так. Вы не понимаете, как работает rollback. Он не уменьшает счетчик транзакций на единицу. Он откатывает ВСЮ транзакцию, полностью. И если вы вызвали процедуру в транзакции, а в ней сказали rollback, то все, получите на выходе ошибку из начального поста. |
9 ноя 12, 13:28 [13445896] Ответить | Цитировать Сообщить модератору |
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] Ответить | Цитировать Сообщить модератору |
Гавриленко Сергей Алексеевич Member Откуда: Moscow Сообщений: 37139 |
Ну нельзя делать rollback в процедуре, если она запущена в транзакции. Хоть ошибка, хоть гномы там зеленые. |
9 ноя 12, 13:58 [13446258] Ответить | Цитировать Сообщить модератору |
alexeyvg Member Откуда: Moscow Сообщений: 31778 |
В процедуре нужно определять, вызывается ли она в транзакции. Если да, то управление транзакциями возложить на вызывающую процедуру (собственно, у вас в вызывающей процедуре и есть это управление) |
||
9 ноя 12, 14:09 [13446375] Ответить | Цитировать Сообщить модератору |
maldalik Member Откуда: Сообщений: 63 |
alexeyvg, Понятно, спасибо, все это придется переписывать. :( Жаль... |
12 ноя 12, 06:11 [13456531] Ответить | Цитировать Сообщить модератору |
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] Ответить | Цитировать Сообщить модератору |
invm Member Откуда: Москва Сообщений: 9633 |
|
|||
12 ноя 12, 09:53 [13456875] Ответить | Цитировать Сообщить модератору |
maldalik Member Откуда: Сообщений: 63 |
invm,
А хбз, говорю же код не мой. Я сам в недоумении, но пока ничего не трогаю пока не пойму как оно работает. Я вообще с MSSQL c 2004 года не работал, на Oracle был. Твой пример мне понятен, но зачем ты его привел не понял. Обработка в вызываемой процедуре верна, или так тоже не прокатит, и надо писать копию процедуры без транзакции? |
||
12 ноя 12, 10:27 [13457045] Ответить | Цитировать Сообщить модератору |
maldalik Member Откуда: Сообщений: 63 |
invm,
А что в 2000 сервере оно есть? |
||
12 ноя 12, 10:28 [13457052] Ответить | Цитировать Сообщить модератору |
alexeyvg Member Откуда: Moscow Сообщений: 31778 |
Нужно контролировать ошибки возвратом какого нибуть кода. |
||||
12 ноя 12, 10:47 [13457149] Ответить | Цитировать Сообщить модератору |
invm Member Откуда: Москва Сообщений: 9633 |
|
||||
12 ноя 12, 10:49 [13457161] Ответить | Цитировать Сообщить модератору |
Топик располагается на нескольких страницах: [1] 2 вперед Ctrl→ все |
Все форумы / Microsoft SQL Server | ![]() |