CommandTimeout

IBX, FIBPlus, UIB, ADO, .Net и прочее-прочее-прочее, в общем все, что относится к созданию приложений, работающих с InterBase, Firebird и Yaffil - клиент-серверных, трехзвенных, консольных и т.п.

Модератор: kdv

Ответить
ARM
Сообщения: 26
Зарегистрирован: 02 дек 2006, 13:27

CommandTimeout

Сообщение ARM » 25 июн 2007, 14:41

Вопрос находится на грани FB и библиотек доступа, но, т.к. используемая платформа библ. доступа - .NET (FB.NET Provider 2.1) и форум по провайдеру не функционирует, спрошу здесь.
Вопрос больше гипотетический, но хотелось бы понять КАК.

Так вот, имеем FB 2.1 Alpha, 2 клиента, .NET 2.0, FB.NET Provider. Первый клиент стартует транзакцию и ДОЛГО пытается изменить данные. До коммита первого клиента, второй также стартует WAIT транзакцию и пытается изменить ТЕЖЕ данные. Соотв. второй (если первый затянет время удержания данных) будет долго ждать.
У FbCommand есть такое свойство - CommandTimeout (тянется от предка DbCommand). Изменяю его, например, на 30 сек для ВТОРОЙ транзакции и запускаю Command. НО по прошествии 30 сек. Комманд не отваливается по таймауту, хотя по логике должен.

Вопрос: Это такая "фича" .НЕТ Провайдера или это FB не отпускает Cоmmand до разблокировки (т.к. используется WAIT транз.) ?

ЗЫ: Предложения о коротких транзакциях не давать, это все и так понятно. Интересует, как можно разрулить такую гипотетическую залипшую транзакцию.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 25 июн 2007, 16:50

Комманд не отваливается по таймауту, хотя по логике должен.
не должен. параметр транзакции wait при конфликте блокировки заставляет транзакцию и коннект "висеть" до тех пор, пока конкурирующая транзакция не завершится.

Вообще, по большому счету, в IB/FB wait применяется редко. В версионнике редко возникает нужда висеть на блокировках.

ARM
Сообщения: 26
Зарегистрирован: 02 дек 2006, 13:27

Сообщение ARM » 25 июн 2007, 17:45

kdv писал(а):
Комманд не отваливается по таймауту, хотя по логике должен.
не должен. параметр транзакции wait при конфликте блокировки заставляет транзакцию и коннект "висеть" до тех пор, пока конкурирующая транзакция не завершится.

Вообще, по большому счету, в IB/FB wait применяется редко. В версионнике редко возникает нужда висеть на блокировках.
Под "редко", я так понимаю, подразумевается только конкурентная запись одних и тех же данных ?

И еще вопрос: так какой же хинт использовать для операций чтения с наибольшей устойчивостью к блокировкам ? Т.е. нужно читать наиболее актуальные данные, соотв. это ReadCommited + (RecVersion or NoRecVersion) + (Wait or NoWait).
Более подходит RecVersion + NoWait, НО после прочтения http://ibase.ru/devinfo/norecver.htm (RecVersion может вывалить deadlock), более "надежным" будет NoRecVersion + Wait.
Поправьте, если не прав.

ЗЫ: Сорри, может быть за обмусоленные вопросы, но почитав здесь несколько статей (особенно, одни пишут, что RecVersion читает без нагрузки на других и с маловероятностью локов, другие пишут, что лок все таки можно выхватить), не нашел консенсуса.

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 25 июн 2007, 18:52

Найди того, кто написал, что можно получить конфликт на чтении в r_c rec_version и плюнь ему в глаз. Два раза, один за себя, другой за меня.

ARM
Сообщения: 26
Зарегистрирован: 02 дек 2006, 13:27

Сообщение ARM » 25 июн 2007, 22:32

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

Как быть ? Рулить только к "наиболее коротким обновляющим транз." ? Например в Мелкософтном сервере любое выполнение отваливается по таймауту. В FB 2.1 я видел isc_lock_timeout, для этого он и нужен ? Жаль, в .НЕТ провайдере его еще не поддерживают....

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 26 июн 2007, 01:24

допустим, кто-то долго что-то обновляет, что-бы не зависнуть навеки, юзаем NoWait. НО при этом сразу будет отвал, т.к. есть блокировка другой транзакцией. Если юзать Wait то ожидание разблокировки необходимых данных уносит в вечность плюс появляется повисшее подключение.
каменный век. если тебе надо что-то долго обновлять - блокируй таблицу целиком. в ibtrans.htm параметры транзакции для этого описаны.
wait использовать для таких целей - я бы даже сказал, маразм :)
например snapshot + wait = маразм :) чего ждать если все равно будет облом.

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

например. в системе есть справочник. модифицировать его разрешено только одному человеку в один момент, т.е. монопольно. Значит, модификацию справочника надо производить в транзакции, монопольно блокирующей всю таблицу. Аминь.

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

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

p.s. ну и, по поводу wait. это как в известном анекдоте про "увидеть динозавра", только 50/50 с пессимистической точки зрения всегда превращаются в облом. Соответственно, зачем ждать, если по окончании ожидания мы с вероятностью 50% получим облом?
И кстати, это даже не 50%. Практика говорит о том, что пользователи отменяют свои действия реже, чем подтверждают их.

ARM
Сообщения: 26
Зарегистрирован: 02 дек 2006, 13:27

Сообщение ARM » 26 июн 2007, 08:43

Спасибо. Краткие ответы по делу, с приемлемой долей критики. :D

ARM
Сообщения: 26
Зарегистрирован: 02 дек 2006, 13:27

Сообщение ARM » 10 июл 2007, 11:30

С появлением FB 2.1 Beta1 и новой фичи - отмена выполнения запроса, хочу реализовать более дружественную для польз. логику по отмене запросов. Хотелось найти наиболее "красивый" вариант.
Итого, имеем FB 2.1 Beta1 + .NET Provider, в БД таблицу mon@statements, в которой есть ID коннекта, транзакции, состояние стэтмента. На стороне клиента имеем запрос либо WAIT, кот. может повиснуть на довольно долгое время, либо NOWAIT, но выгребающий много данных (отчет). Нужно реализовать логику таймуата выполнения запроса. В плоскости работы с БД это вижу как:
1) открыли коннекш, стартовали транзакцию
2) вызываем SP, которая возвращает current_transaction
3) запускаем запрос
4) если вышло время ожидания, то вызываем SP, которая по п.2 + mon@state=1 киляет запрос.

Вроде все гуд, но может есть более красивые варианты ? Поделитесь, кто как делает ?

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 10 июл 2007, 11:46

ARM писал(а): На стороне клиента имеем запрос либо WAIT, кот. может повиснуть на довольно долгое время, либо NOWAIT, но выгребающий много данных (отчет).
Чёта в доме еблонских как всё перепуталось, так и не распутывается.
ARM писал(а): Вроде все гуд, но может есть более красивые варианты ? Поделитесь, кто как делает ?
Просто делают. Конфликты обновления обслуживают в nowait, кривых запросов с непрогнозируемым временем выполнения на сервак не отправляют. Оптимизацией, типа, занимаются, а не рассчитывают на волю Аллаха. Ну а если уж отчёт должен строиться полчаса, то он полчаса и строится.

Ответить