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

Все общение с сервером построено исключительно на вызовах хранимых процедур. На стороне клиента присутствуют только операторы запуска этих хранимых процедур. Транзакции открываются и закрываются только в теле этих процедур. Код проверен - транзакции всегда закрываются.
Иногда происходит "зависание" транзакции - программа из sp выходит без всяких ругательств, но транзакция остается открытой - естественно, в последствии все изменения, вносимые пользователем, будут утрачены при выходе из программы. Пробовал с этим бороться при входе в процедуру проверяя количество открытых транзакций - не получилось, возвращается единица, но при попытке закрыть транзпкцию - вылет по ошибке - нет открытых транзакций....
Наверняка я чего-то не понимаю, но вот чего!?

И второй вопрос:
как народ борется со следующей ситуацией:
есть, например, такой код:

BEGIN TRAN
Select I_D, mName From tbl_Test
IF @@error <> 0
BEGIN
Rollback Tran
Return
END
ELSE
BEGIN
COMMIT TRAN
END

при этом, если я изменю в таблице название поля, которое учавствует в select, то все вылетит по ошибке, и при этом никаких откатов не произойдет - транзакция останется открытой. Я конечно, понимаю, что менять названия поля нехорошо, но в процессе постоянных доработок это иногда происходит ...
...
Рейтинг: 0 / 0
"Зависание" транзакции
    #32030584
Фотография Александр Гладченко
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Приведите пример процедуры, с которой возникают эти казусы...
...
Рейтинг: 0 / 0
"Зависание" транзакции
    #32030659
Фотография cvasil
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
На счет второго вопроса:

Если уж по другому никак не получается, то можно выкрутиться вот так:

DECLARE @rc INT
BEGIN TRAN
EXEC @rc=sp_executesql N'suspicious SQL statement'
IF @rc <> 0 BEGIN
-- exception handling here
...
ROLLBACK TRAN
END ELSE BEGIN
COMMIT TRAN
END

PRINT @@TRANCOUNT


Правда ошибки с Severity Levels 20 и выше приводят к закрытию текущей сессии.
В этом случае вышеприведенный метод не работает.
...
Рейтинг: 0 / 0
"Зависание" транзакции
    #32030720
pogues
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Если я не ошибаюсь, то MSSQL проверяет число открытых транзакций до и после выполнения процедуры.
create proc My_proc2 AS BEGIN TRAN

exec My_proc2

Так что ругать ся должно.
...
Рейтинг: 0 / 0
"Зависание" транзакции
    #32030748
Hibernate
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пример-то как раз привести не могу - на какой именно процедуре это происходит установить невозможно - пользователь продолжает нормально работать и даже не догадывается о том, что какая-то там транзакция "повисла" - а я замечаю "зависание" транзакции слишком поздно, когда мне сообщают о блокировках, - за это время люди успевают по сотне-полторы раз обратиться к серверу.
Я пока борюсь с этим ручками - мониторю счетчик "Active tranzactions" - и как только замечаю достаточно продолжительную - sp_who затем Kill. Отключение одного процесса помогает в 90 % случаев, иногда приходится убить 2-3 коннекшина. Опрос отключенных юзеров ничего не дал - все они работают в совершенно разных отделах и выполняют разные функции - это значит, что быстрее всего я чего-то глобально не понимаю и делаю одинаковую принципиальную ошибку во многих местах.
Могу привести пример стандартного оформления транзакций во всех sp:

BEGIN TRAN
INSERT INTO tbl_2_Goods (GoodsNameID, Cost, StockPlaceID) VALUES (@GoodsNameID, 0, @StockPlaceID)
SET @GoodsID = @@Identity
IF @@Error<>0
BEGIN
ROLLBACK TRAN
RAISERROR 13091'Операция отменена!'
RETURN
END
SELECT @StockIDTo = StockID FROM dbo.tbl_2_LogisticOrders WHERE (LogisticOrderID = @LogisticOrderID)

IF @StockIDTo IS NULL
BEGIN
ROLLBACK TRAN
RAISERROR 13092'Не задан склад контракта! Операция отменена!'
RETURN
END
INSERT INTO tbl_2_LogisticOrderGoods(LogisticOrderID, GoodsID, OrderedQuantity, DeliveredQuantity, IncompliteQuantity) VALUES (@LogisticOrderID, @GoodsID, 0, 0, @IncompliteQuantity)
IF @@Error<>0
BEGIN
ROLLBACK TRAN
RAISERROR 13091'Операция отменена!'
RETURN
END

COMMIT TRAN
RETURN

Подобным образом транзакции оформлены везде...
...
Рейтинг: 0 / 0
"Зависание" транзакции
    #32030754
Hibernate
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>ли я не ошибаюсь, то MSSQL проверяет число открытых транзакций до и после выполнения процедуры.
>create proc My_proc2 AS BEGIN TRAN
>exec My_proc2
>
>Так что ругать ся должно.

Такая ситуация нормально обрабатывается клиентским приложением, и никаких проблем не возникает. Но в моем случае никакого ругательства не происходит - пользователь без проблем продолжает работать.
Пример - добавление товаров в заказ: были случаи, кода пользователь добавил 20 позиций, после чего я его отрубил - после перезапуска клиентского приложения в заказе осталось 12 позиций. И это при том, что добавление позиций происходит так: двойной клик мышки по справочнику, вызов sp добавления, следующий двойной клик.
Процедуру добавления позиции в заказ облазил вдоль и впоперек - все нормально, причем эту-же процедуру вызывает еще 60 человек в пяти офисах по сотне раз в день...
...
Рейтинг: 0 / 0
"Зависание" транзакции
    #32030755
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я, конечно, не уверен, но то, что бросается в глаза:

1. Проверять код ошибки необходимо СРАЗУ за подозрительной командой, т.е. код должен быть примерно таким:

DECLARE @SaveError Int
SET @SaveError=0

INSERT ...
SET @SaveError=@@ERROR
...
IF @SaveError<>0 ... ELSE ...

Ты же вставил после команды INSERT команду присвоения SET, которая разумеется завершилась без ошибок и после ее выполнения системная переменная @@ERROR благополучно приняла значение 0

2. Не делай несколько точек выхода из процедуры (несколько RETURN). За ними очень трудно проследить и это место потенциальных ошибок. Делай безусловный переход по меткам (GOTO)

Примерный код:

DECLARE @SaveError Int
SET @SaveError=0

BEGIN TRANSACTION
...
INSERT ...
SET @SaveError=@@ERROR
...
IF @SaveError<>0 GOTO StopTran
...

StopTran:
IF @@TranCount>0
IF @SaveError=0 COMMIT TRANSACTION
ELSE ROLLBACK TRANSACTION

RETURN
...
Рейтинг: 0 / 0
"Зависание" транзакции
    #32030760
Deem
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А может, клиент не завершает транзакцию соединения?
...
Рейтинг: 0 / 0
"Зависание" транзакции
    #32030818
Hibernate
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
по поводу нескольких точек выхода из программы- тут я почти согласен, но такой уж стиль у меня выработался, плюс терпеть не могу GOTO.
>1. Проверять код ошибки необходимо СРАЗУ за подозрительной командой, т.е. код должен быть примерно таким:

спасибо за новую мысль - попробую.
Но насколько я понимаю, весли я выйду из sp и при этом перед выходом останется открытая транзакция, то сервер должен ругнуться на это и транзакцию прибить(всегда ли это так?)... но ничего такого не происходит - транзакция остается открытой...
Мистика какая-то, причем ситуация не изменилась при переходе с v70_sp2->v70_sp3->v70_sp4->v2k_sp2

>RE: Deem
>А может, клиент не завершает транзакцию соединения?

к счастью, на клиенте нет ни одной команды кроме как открытие коннекшина и ADODB.Command.Execute.
Нет ни одного асинхронного запроса - только синхронный режим.
...
Рейтинг: 0 / 0
"Зависание" транзакции
    #32030826
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообще-то, насколько я понимаю, если не была дана специальная команда, то транзакция будет жить все время существования текущего соединения. При закрытии соединения все открытые транзакции автоматически откатываются (ROLLBACK). И я не вижу тут причины для сообщения об ошибке.

Посмотри еще текущую настройку SET IMPLICIT_TRANSACTION.

По умолчанию она в OFF. Если она выставлена в ON, то у тебя будут автоматически открываться транзакции при выполненнии некоторых команд. А вот автоматически закрываться не будут.
...
Рейтинг: 0 / 0
"Зависание" транзакции
    #32030835
Hibernate
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
> Вообще-то, насколько я понимаю, если не была дана специальная команда, то транзакция будет жить все время
> существования текущего соединения. При закрытии соединения все открытые транзакции автоматически откатываются
> (ROLLBACK). И я не вижу тут причины для сообщения об ошибке.

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

Begin Tran
Insert Into tbl_TestTran (mName) Select LEFT(mName,50) From tbl_GoodsNAmes

и если в приложении эту ошибку перехватить и спрятать типа On Error Resume Next, то эта транзакция так и останется!

Похоже, проблема в клиентском приложении - иногда ошибка почему-то не перехватывается, но это уже дело техники и обсуждения не стоит.

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


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