Вопрос по TPB, и FIB+ до кучи :)
-
- Сообщения: 250
- Зарегистрирован: 25 июл 2007, 21:33
Вопрос по TPB, и FIB+ до кучи :)
Правильно ли я понимаю следующие вещи:
1. При работе с TpFIBTransaction для разделения транзакций на "длинные" читающие, и "короткие" пишущие, с целью гибкого управления параметрами транзакций (заполнения TPB нужными константами) необходимо выставлять свойство TpFIBTransaction TPBMode не в значение tpbReadCommitted, а в tpbDefault, потому что иначе не получится заполнять TPB, так как заполнен он будет автоматически?
2. Лучше создать в программе ОДНУ длинную читающую транзакцию с параметрами TPB:
isc_tpb_read
isc_tpb_nowait
isc_tpb_read_committed
isc_tpb_rec_version
Как я понял такие параметры TPB не дадут "заморозить" OIT и вызовут минимальную нагрузку на сервер?
3. В этом случае можно "перечитывать" данные отображаемые "только для чтения" с помощью метода FullRefresh который неявно использует isc_commit_retaining ?
4. Для "коротких" пишущих транзакций использовать параметры TPB:
isc_tpb_write
isc_tpb_wait
isc_tpb_read_committed
isc_tpb_rec_version
(можно по идее и isc_tpb_no_rec_version - в случае когда ВСЕ пишущие транзакции "короткие", это не будет играть существенной роли, так как установлено isc_tpb_wait и при возможной блокировке из другого приложения транзакция "подождёт")
4. В принципе для нужд записи может быть достаточно ОДНОЙ "короткой" пишущей транзакции, на которую будут ссылаться все выполняющие добавление и обновление данных компоненты?
Кстати, оговорюсь - в моём случае вариант "конкурентной борьбы за одну запись" практически исключён бизнес-логикой приложения. То есть потенциальные блокировки (а в данном случае скорее "ожидания") относятся как правило к добавлению записей разными пользователями в одну таблицу. Но даже если происходит попытка одновременного редактирования одной и той же записи, как правило разные пользователи будут редактировать разные поля этой таблицы, то есть меня устраивает вариант, когда первый
пользователь стартует "короткую" пишущую транзакцию, второй при попытке редактирования этой же записи "висит" в ожидании, и после того, как первый пользователь подтверждает изменения, второй вносит свои изменения. Бизнес логике в данном случае
это не повредит (пример - попытка одного диспетчера "отдать" заказ исполнителю и одновременно попытка подредактировать неправильно указанный изначально адрес заказа другим диспетчером)
Огромная просьба - если я что-то упустил, или неправильно понимаю, укажите пожалуйста!
Ведь базис очень важен. Лучше сразу чётко понимать от чего отталкиваться...
1. При работе с TpFIBTransaction для разделения транзакций на "длинные" читающие, и "короткие" пишущие, с целью гибкого управления параметрами транзакций (заполнения TPB нужными константами) необходимо выставлять свойство TpFIBTransaction TPBMode не в значение tpbReadCommitted, а в tpbDefault, потому что иначе не получится заполнять TPB, так как заполнен он будет автоматически?
2. Лучше создать в программе ОДНУ длинную читающую транзакцию с параметрами TPB:
isc_tpb_read
isc_tpb_nowait
isc_tpb_read_committed
isc_tpb_rec_version
Как я понял такие параметры TPB не дадут "заморозить" OIT и вызовут минимальную нагрузку на сервер?
3. В этом случае можно "перечитывать" данные отображаемые "только для чтения" с помощью метода FullRefresh который неявно использует isc_commit_retaining ?
4. Для "коротких" пишущих транзакций использовать параметры TPB:
isc_tpb_write
isc_tpb_wait
isc_tpb_read_committed
isc_tpb_rec_version
(можно по идее и isc_tpb_no_rec_version - в случае когда ВСЕ пишущие транзакции "короткие", это не будет играть существенной роли, так как установлено isc_tpb_wait и при возможной блокировке из другого приложения транзакция "подождёт")
4. В принципе для нужд записи может быть достаточно ОДНОЙ "короткой" пишущей транзакции, на которую будут ссылаться все выполняющие добавление и обновление данных компоненты?
Кстати, оговорюсь - в моём случае вариант "конкурентной борьбы за одну запись" практически исключён бизнес-логикой приложения. То есть потенциальные блокировки (а в данном случае скорее "ожидания") относятся как правило к добавлению записей разными пользователями в одну таблицу. Но даже если происходит попытка одновременного редактирования одной и той же записи, как правило разные пользователи будут редактировать разные поля этой таблицы, то есть меня устраивает вариант, когда первый
пользователь стартует "короткую" пишущую транзакцию, второй при попытке редактирования этой же записи "висит" в ожидании, и после того, как первый пользователь подтверждает изменения, второй вносит свои изменения. Бизнес логике в данном случае
это не повредит (пример - попытка одного диспетчера "отдать" заказ исполнителю и одновременно попытка подредактировать неправильно указанный изначально адрес заказа другим диспетчером)
Огромная просьба - если я что-то упустил, или неправильно понимаю, укажите пожалуйста!
Ведь базис очень важен. Лучше сразу чётко понимать от чего отталкиваться...
1. гм. tpbDefault - это параметры транзакции по умолчанию, у FIBPlus. См. документацию по ним. Поэтому, откуда взято "необходимо" - не ясно.
2.
ты разве не читал www.ibase.ru/devinfo/ibx.htm и ibtrans.htm ?
3. да что угодно. и commit_retaining тут не нужен
4. зачем использовать wait ??? зачем использовать no_rec_version ???
почему именно одну?
опять же, читай www.ibase.ru/devinfo/ibx.htm - там написано про "одну и много".
2.
ты не понял. вообще. OIT застревает при явном rollback. при чем тут читающая транзакция? Читающая транзакция просто стартует в pre-committed, и не считается активной (на сервере).Как я понял такие параметры TPB не дадут "заморозить" OIT и вызовут минимальную нагрузку на сервер?
ты разве не читал www.ibase.ru/devinfo/ibx.htm и ibtrans.htm ?
3. да что угодно. и commit_retaining тут не нужен
4. зачем использовать wait ??? зачем использовать no_rec_version ???
почему именно одну?
опять же, читай www.ibase.ru/devinfo/ibx.htm - там написано про "одну и много".
ну. мог бы проверить. второй после коммита первого обломится.второй при попытке редактирования этой же записи "висит" в ожидании, и после того, как первый пользователь подтверждает изменения, второй вносит свои изменения.
надо внимательно читать статьи, и ПРОБОВАТЬ.Огромная просьба - если я что-то упустил, или неправильно понимаю, укажите пожалуйста!
Ведь базис очень важен. Лучше сразу чётко понимать от чего отталкиваться...
-
- Сообщения: 250
- Зарегистрирован: 25 июл 2007, 21:33
1. Ну, под "необходимо" я имел в виду - необходимо для самостоятельного управления TPB. Если поставить явно tpbReadCommitted то буфер параметров заполнится автоматически,
(isc_tpb_write
isc_tpb_nowait
isc_tpb_rec_version
isc_tpb_read_committed)
и менять его не получится.
А если я хочу создать долгоживущую транзакцию только для чтения, не создающую мусорные версии записей, то задать соответствующие параметры можно только при tpbDefault - вот что я имел в виду.
2. Ага, с этим разобрался вроде.
3. Погоди, почему не нужен? Это же получается весьма удобно при наличии длинной читающей транзакции? Выполнил для обновления данных FullRefresh и готово! Вместо запоминания первичного ключа, отключения DataSet.DisableControls затем DataSet.Close DataSet.Open и восстановления позиции указателя и снова подключения DataSet'а, да еще с учётом, что запись может быть удалена другим пользователем!
4. Немного не понял - как это зачем? Или ты про то, что isc_tpb_wait используется по-умолчанию и явно задавать его необязательно? Ну я просто для полноты картины привожу все значения TPB в том числе и те, которые можно опустить... А как же без wait в короткой пишущей транзакции? При no_wait и сетевой работе постоянно можно получать конфликты блокировки тогда? И насчёт no_rec_version - в короткой пишущей транзакции вроде это будет правильным, чтобы гарантировать что идёт работа действительно с последней версией записи. Совместно с wait самое оно вроде как?
А насчёт одна или много пишущих транзакций, это да, еще недопонимаю всего - продолжаю читать и экспериментировать пока, чтобы определиться...
По последнему:
Да, тут я слашЫл... Я считал, что если два пользователя редактируют РАЗНЫЕ поля одной записи, то после коммита первого транзакция с wait второго "отвиснет" и произведёт свои изменения, в результате чего сохранится и правка первого и второго. Виноват, недопонял. Действительно будут сохранены только последние изменения, то есть измененния второго пользователя... А обломается второй после коммита первого или нет - это еще вопрос Какие параметры TPB заданы будут... Если будет стоять скажем
write
read_committed
wait
no_rec_version
то очень даже не обломается второй Его изменения и сохранятся в результате... Другое дело правильно ли это с точки зрения логики программы или нет.
(isc_tpb_write
isc_tpb_nowait
isc_tpb_rec_version
isc_tpb_read_committed)
и менять его не получится.
А если я хочу создать долгоживущую транзакцию только для чтения, не создающую мусорные версии записей, то задать соответствующие параметры можно только при tpbDefault - вот что я имел в виду.
2. Ага, с этим разобрался вроде.
3. Погоди, почему не нужен? Это же получается весьма удобно при наличии длинной читающей транзакции? Выполнил для обновления данных FullRefresh и готово! Вместо запоминания первичного ключа, отключения DataSet.DisableControls затем DataSet.Close DataSet.Open и восстановления позиции указателя и снова подключения DataSet'а, да еще с учётом, что запись может быть удалена другим пользователем!
4. Немного не понял - как это зачем? Или ты про то, что isc_tpb_wait используется по-умолчанию и явно задавать его необязательно? Ну я просто для полноты картины привожу все значения TPB в том числе и те, которые можно опустить... А как же без wait в короткой пишущей транзакции? При no_wait и сетевой работе постоянно можно получать конфликты блокировки тогда? И насчёт no_rec_version - в короткой пишущей транзакции вроде это будет правильным, чтобы гарантировать что идёт работа действительно с последней версией записи. Совместно с wait самое оно вроде как?
А насчёт одна или много пишущих транзакций, это да, еще недопонимаю всего - продолжаю читать и экспериментировать пока, чтобы определиться...
По последнему:
Да, тут я слашЫл... Я считал, что если два пользователя редактируют РАЗНЫЕ поля одной записи, то после коммита первого транзакция с wait второго "отвиснет" и произведёт свои изменения, в результате чего сохранится и правка первого и второго. Виноват, недопонял. Действительно будут сохранены только последние изменения, то есть измененния второго пользователя... А обломается второй после коммита первого или нет - это еще вопрос Какие параметры TPB заданы будут... Если будет стоять скажем
write
read_committed
wait
no_rec_version
то очень даже не обломается второй Его изменения и сохранятся в результате... Другое дело правильно ли это с точки зрения логики программы или нет.
это фича FIBPlus, здесь ее обсуждать вряд-ли имеет смысл.вот что я имел в виду.
в дизайнере свойств транзакции можно и свои создавать. но это для дизайна. В общем, ты куда-то не в ту степь уехал в рассуждениях о транзакциях.и менять его не получится.
3. для read read_committed завершение по retaining НЕ НУЖНО ибо не имеет смысла. Другое дело, что оно МОЖЕТ вызываться при текущей функциональности компонент - это совсем другое дело.
а нафиг? блин. у транзакции есть параметры. они либо нужны, когда ты хочешь получить некое поведение транзакций, либо нет.А как же без wait в короткой пишущей транзакции?
бред какой-то. см. ibtrans.htm. я в том смысле что wait и nowait имеют разницу в обработке конфликтов. Которая может быть нужна или не нужна. Чтобы ее использовать, нужно ее понимать. Или попробовать, устраивает такое поведение тебя, или нет. Вместо того, чтобы тут домыслы по паре страниц расписыватьПри no_wait и сетевой работе постоянно можно получать конфликты блокировки тогда?
по использованию no_rec_version есть отдельная статья на сайте.то очень даже не обломается второй
-
- Сообщения: 250
- Зарегистрирован: 25 июл 2007, 21:33
Ну возможно кто-то действительно ставит целью приложения - получить как можно больше конфликтов блокировки, тогда оно конечно да... Просто не могу себе представить реальную ситуацию, в которой запись идёт с помощью "короткой" транзакции и БЕЗ wait... Какая бы она короткая не была, в реальном многопользовательском сетевом приложении вероятность "пересечения" всё же высока получится... Я конечно сейчас и другие варианты пробую - и no_wait в том числе и обработка возможного конфликта на клиенте... Что удобнее и лучше - покажут результаты тестов, как предварительных, так и "рабочих"...kdv писал(а):а нафиг? блин. у транзакции есть параметры. они либо нужны, когда ты хочешь получить некое поведение транзакций, либо нет.А как же без wait в короткой пишущей транзакции?
Пока я на тестовых примерах которые рекомендуют в статьях по работе с транзакциями с помощью FIB+ работаю, но вот натолкнулся на отличие от статьи по NO_RECORD_VERSION
При трёх копиях тестовой программы почему-то работает нифига не так, как в статье описано То есть конфликт всё-таки получаю... Буду подробнее смотреть, может что не так настроил, но вроде всё ОК. Надо завтра на свежую голову еще раз будет проверить подробно...
NO_REC_VER не гарантирует отсутствие конфликтов, она лишь уменьшает их вероятность. Явной очереди ожидающих нет, так что возможны конфликты на второй стадии (когда две транзакции дождались завершения первой и обе независимо ломанулись апдейтить).Kotъ-Begemotъ писал(а):натолкнулся на отличие от статьи по NO_RECORD_VERSION :(
При трёх копиях тестовой программы почему-то работает нифига не так, как в статье описано :( То есть конфликт всё-таки получаю...
-
- Сообщения: 144
- Зарегистрирован: 16 фев 2006, 22:36
-
- Сообщения: 250
- Зарегистрирован: 25 июл 2007, 21:33
Нда... Это конечно не есть хорошо... Хотя никто не мешает сделать цикл со счётчиком и в нём пытаться проапдейтить запись, вываливаясь по ошибке только при истечении ХХ или ХХХ попыток... В общем всё в руках программера, хотя иногда хотелось бы часть переложить на кого-то или на что-то ))dimitr писал(а):Явной очереди ожидающих нет, так что возможны конфликты на второй стадии (когда две транзакции дождались завершения первой и обе независимо ломанулись апдейтить).
И еще просто удивило что ошибку блокировки получает ВТОРАЯ транзакция, однако, несмотря не это, в итоге в таблице сохраняются именно изменения сделанные этой второй транзакцией! Я понимаю отработало бы, и третяя транзакция бы получила ошибку - вроде логично... Это несколько и удивило...
В общем-то полностью я изложил этот вопрос на Форуме по FIB+ но форум свежеиспечёный, поэтому пока там молчок...
А ты при ошибке блокировки во второй транзакции что делаешь?Kotъ-Begemotъ писал(а):
И еще просто удивило что ошибку блокировки получает ВТОРАЯ транзакция, однако, несмотря не это, в итоге в таблице сохраняются именно изменения сделанные этой второй транзакцией! Я понимаю отработало бы, и третяя транзакция бы получила ошибку - вроде логично... Это несколько и удивило...
Commit или Rollback?
-
- Сообщения: 250
- Зарегистрирован: 25 июл 2007, 21:33
-
- Сообщения: 250
- Зарегистрирован: 25 июл 2007, 21:33
Ну в прямом смысле.kdv писал(а):в смысле?И это изменение сохраняется, несмотря на ошибку!
update
ошибка
commit - в результате update прошел? не может такого быть.
1. Стартую последовательно 3 транзакции. В первой меняю запись. Не подтверждаю пока.
2. Во второй тоже меняю эту запись. Транзакция 2 "подвисает" в ожидании первой.
3. В третей тоже меняю эту же запись. Транзакция 3 тоже "подвисает".
4. Commit Транзакции 1. Транзакция 2 "отвисла", но подвисла уже Транзакция 1.
5. Commit Транзакции 2. По идее должен получить или ошибку и обломаться с апдейтом, или апдейт должен пройти? А я получаю ошибку блокировки, И запись остаётся той, на котору менял в Транзакции 2...
Тутподробно описано по шагам что делаю
-
- Сообщения: 144
- Зарегистрирован: 16 фев 2006, 22:36
-
- Сообщения: 144
- Зарегистрирован: 16 фев 2006, 22:36
-
- Сообщения: 250
- Зарегистрирован: 25 июл 2007, 21:33