Форум: "Базы";
Текущий архив: 2004.07.25;
Скачать: [xml.tar.bz2];
Вниздва TIBTransaction ! Найти похожие ветки
← →
GanibalLector © (2004-07-01 12:53) [0]Решил разобраться как работать с двумя компонентами TIBTransaction(одна на запись,вторая на чтение).Раньше,все в одной делал и после Commit все открывал заново. Итак имею следующее:
WR_IB.params=write,consistency,read_committed,rec_version,nowait
RD_IB.params=read,consistency,read_committed,rec_version,nowait
IBDataBase1.DefaultTransaction=RD_IB.
Дальше,вставляю что-либо в таблицу через IBQuery1 и связанный с ним IBUpdateSQL(кстати IBQuery1.Transaction=WR_IB) например так:
Ibquery1.Insert;
Ibquery1.FieldByName("mod").value:=17;
Ibquery1.FieldByName("model").value:="Talla2k";
Ibquery1.FieldByName("ser").value:="88";
Ibquery1.Post;
if WR_IB.InTransaction=false then
WR_IB.StartTransaction;
WR_IB.Commit;
все чудесно вставилось,НО !!!
По моему IMHO вставленная запись должна была моментально появиться в IBQuery2,который связан с RD_IB ,а ее нет.
В чем я не прав?
← →
Sergey_Masloff (2004-07-01 12:56) [1]В чем я не прав?
Во всем от начала до конца. Это делается не так.
особенно меня умилило вот это:
WR_IB.StartTransaction;
WR_IB.Commit;
← →
GanibalLector © (2004-07-01 13:00) [2]2 Sergey_Masloff
>Во всем от начала до конца.
Ну а подробности???
>особенно меня умилило вот это
И что-же там не правильного???
← →
Sergey_Masloff (2004-07-01 13:11) [3]1) С UpdateSQL не получится.
(есть патч сторонний для IBX если хочешь ищи на ibase.ru я его не использовал никогда)
2) Можно делать так: (подробно не напишу потому что у меня это закрыто своим классом который публиковать не могу)
- к IBQuery цепляется UpdateSQL c "пустыми" но валидными SQL (например select null from rdb$database)
- обновление осуществляется отдельным IBSQL работающим в своей транзакции
- при подтверждении кэшированных изменений заполняшь IBSQL значениями параметров выполняешь и коммитишь (пишущую транзакцию). У меня все изменения выполняются черех XP но это может быть и простой запрос - у меня есть специфика.
>И что-же там не правильного???
То что если Query у тебя открыт то транзакция УЖЕ стартована. Но даже если вдруг она бы оказалась не стартованой (что ты видимо предполагал) то ты ей делаешь старт и сразу коммит (а чего она коммитить тебе будет? Не подскажешь?)
;-)
← →
GanibalLector © (2004-07-01 13:11) [4]2 Sergey_Masloff
Может примерчик подарите???
mailto:Talla2k@ukr.net
← →
Sergey_Masloff (2004-07-01 13:14) [5]GanibalLector © (01.07.04 13:11) [4]
С примером не помогу - у меня там комплексный класс с тучей заточенного под конкретную идеологию кода да и проект коммерческий нельзя такое публиковать. Я только автор но не владелец кода. Может быть завтра вечером если время будет попробую простой пример состряпать. Ели еще не разберешься к тому времени
← →
GanibalLector © (2004-07-01 13:16) [6]2 Sergey_Masloff
>Может быть завтра вечером если время будет попробую простой пример состряпать
Был бы ОЧЕНЬ признателен!
← →
Соловьев © (2004-07-01 13:17) [7]
> По моему IMHO вставленная запись должна была моментально
> появиться в IBQuery2,который связан с RD_IB ,а ее нет
с какой это стати?
Переоткрой эту квери и увидишь
← →
Наталия © (2004-07-01 13:20) [8]Sergey_Masloff
По-моему ты опять вопрос по диагонали прочитал :))
GanibalLector © (01.07.04 13:11)
Мне кажется, что после вставки записей одной транзакцией, запрос на чтение в другой (RD_IB) нужно переоткрыть.
← →
kaif © (2004-07-01 13:30) [9]2 GanibalLector ©
1. Стартуй транзакцию до того, как открываешь запрос.
if WR_IB.InTransaction=false then
WR_IB.StartTransaction;
IBQuery1.Open;
Ibquery1.Insert;
Ibquery1.FieldByName("mod").value:=17;
Ibquery1.FieldByName("model").value:="Talla2k";
Ibquery1.FieldByName("ser").value:="88";
Ibquery1.Post;
WR_IB.Commit;
После всех этих трудов, переоткрываешь свой "второй запрос", в котором хочешь видеть изменения. Транзакция у того запроса должна быть read_committed - здесь ты был прав, но запрос все равно надо переоткрыть. Если не указать read_committed, то даже после переоткрытия, второй запрос изменений не увидит - нужно будет перестартовать вторую транзакцию тоже, чтобы он что-то подтвержденное в других транзакциях увидел.
← →
Sergey_Masloff (2004-07-01 13:31) [10]Наталия © (01.07.04 13:20) [8]
>По-моему ты опять вопрос по диагонали прочитал :))
Не-а. Сейчас все четко ;-)
>запрос на чтение в другой (RD_IB) нужно переоткрыть
это само собой. Суть не в этом.
Зачем нужна пишущая транзакция? Чтобы открыться сделать быстрое действие и закоммититься. Никакие визуальные компоненты, да и вообще никакие датасеты к ней цеплять нельзя - потому что получаем кучу проблем и не получаем НИКАКОГО выигрыша. Именно это я и пытаюсь пояснить.
Ну и еще то место где транзакция зачем-то проверяется на открытость. Если в датасете что-то есть то транзакция открыта по-любому.
← →
Sergey_Masloff (2004-07-01 13:33) [11]kaif © (01.07.04 13:30) [9]
Все это так но я не понимаю зачем пишущей транзакции связь с датасетом? Просто потому что прочитано что 2 транзакции это круто? Конечно что ты пишешь будет работать но зачем? Никаких проблем решаемых применением отдельной пишущей транзакции такой подход не решит, объем кода (и потенциальных ошибок) вырастет... оно надо?
← →
GanibalLector © (2004-07-01 13:57) [12]2 Sergey_Masloff
Скажите,а в чем же плюсы двух TIBTransaction?Если хоть так,хоть эдак прийдется все переоткрывать.В чем смысл?
И еще...я тут просто для примера добавляю запись через IBQuery и связанный с ним IBUpdateSQL,реально это все будет через ХП.
← →
GanibalLector © (2004-07-01 14:00) [13]>Чтобы открыться сделать быстрое действие и закоммититься. Никакие визуальные компоненты, да и вообще никакие датасеты к ней цеплять нельзя - потому что получаем кучу проблем и не получаем НИКАКОГО выигрыша. Именно это я и пытаюсь пояснить.
Ну...и если использовать ХП для записи и один TIBTransaction.В чем,собственно,будет разница???
← →
jack128 © (2004-07-01 16:00) [14]
> GanibalLector
я ж тебе кидал линк на статью на delphiplus.org.. А ты видимо решил пойти своим путем ;-) Тот метод каким ты пытаешься пойти дает хронические тормоза на более менее тяжелых запросах..
> Скажите,а в чем же плюсы двух TIBTransaction?Если хоть так,хоть
> эдак прийдется все переоткрывать.В чем смысл?
в том что ты вообще не в ту степь пошел. Нужно писать наследника TIBDataSetUpdateObject..
В IBX сделано так, что IBDataSet может делегирует ответственность за вставку/изменение записей на другой класс. Этот другой класс должен наследоваться от TIBDataSetUpdateObject. Как именно UpdateObject( - cвойство IbDataSet"а - это и есть наш наследник TIBDataSetUpdateObject) будет изменять данные на сервере датасет абсолютно не волнует. Именно этим и нужно воспользоваться,что разделить в IBX транзакции на чтение и запись..
> Ну...и если использовать ХП для записи и один TIBTransaction.В
> чем,собственно,будет разница???
нет. Какая размица как ты вставляешь записи.. Главное в каких транзакциях ты это делаешь..
← →
GanibalLector © (2004-07-01 16:04) [15]>я ж тебе кидал линк на статью на delphiplus.org..
м-да...я не видел ничего.Куда кидал???
← →
GanibalLector © (2004-07-01 16:15) [16]2 Jack128
>Какая размица как ты вставляешь записи.. Главное в каких транзакциях ты это делаешь..
Что-то я совсем запутался...ты говоришь одно,Sergey_Masloff другое.Не пойму,ГДЕ ПРАВДА???
Хорошо,поставлю вопрос по другому,ЧТО измениться,если я буду делать в двух транзакциях???Быстрее что-ли???Или правильней???
← →
jack128 © (2004-07-01 16:23) [17]
> м-да...я не видел ничего.Куда кидал???
в асю..
http://delphiplus.nagano.ru/articles/components/ibupdatesqlw.htm
> говоришь одно,Sergey_Masloff другое
Сергей говорит тоже самое:
> 1) С UpdateSQL не получится.
> (есть патч сторонний для IBX если хочешь ищи на ibase.ru
> я его не использовал никогда)
Вот про это я тебе и говорю.. Просто в той статье изменяется уже существующий TIbUpdateSQL, а я предпочел написать своего наследника..
← →
GanibalLector © (2004-07-01 16:29) [18]2 jack128
от тебя в Асе ничего не было.Бывает...
На счет ссылки.Не открывается она.The page cannot be found
← →
Sergey_Masloff (2004-07-01 16:31) [19]Да мы с jack128 © говорим о двух разных реализациях одного и того же. У меня правда сделано по другому но как я уже сказал по идеологическим соображениям ;-) Но в результате функциональность абсолютно та же - датасету становится абсолютно по фиг как изменяются данные на сервере.
Кстати у меня отдельные транзакции не были целью - изначально нужен был универсальный метод применения изменений произвольной сложности (по многим таблицам и так далее) для BDE. Потом модифицировано для IBX а потом добавкой 3 строк кода - для работы в отдельной транзакции ;-)
← →
Dazhan (2004-07-01 16:55) [20]Кажется, компонент назывался IBUpdateSQLW, тот, что позволяет вторую транзакцию подключить к IBQuery. Его исходник есть на ibase.ru
← →
jack128 © (2004-07-01 17:13) [21]
> Кажется, компонент назывался IBUpdateSQLW,
угу. Именно он.
Ссылка, которую я дал, битая потому я "l" забыл дописать в конце. Вот правильная, если кому интересно: http://delphiplus.nagano.ru/articles/components/ibupdatesqlw.html
← →
jack128 © (2004-07-01 17:50) [22]
> ЧТО измениться,если я буду делать в двух транзакциях???Быстрее
> что-ли???Или правильней???
Хе. Не обратил внимание на самый важный вопрос: нафиг вообще все это нужно :-)
Все весьма просто. Пока транзакция, которая изменила запись не завершиться мы не можем сново изменить/удалить эту запись - возникнет конфликт обновлений. Чтобы уменьшить вероятность таких конфликтов нужно чтобы пишущие транзакции были как можно короче. Вот именно этого мы и добиваемся.
← →
Sergey_Masloff (2004-07-01 17:52) [23]>Вот именно этого мы и добиваемся.
Угу. и версий чтобы плодить меньше потому что даже без конфликтов серверу с ними тяжелей работается. Он, конечно, железный но...
← →
GanibalLector © (2004-07-01 20:48) [24]2 jack128
>Пока транзакция, которая изменила запись не завершиться мы не можем сново изменить/удалить эту запись - возникнет конфликт обновлений
Ну наконец-то я догнал.Это так называемая блокировка записей.
Дык,по моему ИМХО это только для тех,кто разрешает править прямо в гриде.
На последок,еще вопросик(ну...а вдруг пригодится):
вот Вы говорите,про конфликт обновлений.В своих программах я обычно не разрешаю править данные в гриде.Обычно это нажатие на кнопку "Изменить"-дальше открытие некой формы-ввод данных- и типа "Сохранить".В "Сохранить" обычно выполняется ХП и commit.
Так вот,а теперь представьте ситуацию,предположим кто-то нажал на "Изменить" и пошел пить водку.Спустя некоторое время,на другом компе решили изменить ту же запись и тоже нажали "Изменить".Смысл в том,что-бы сказать юзеру,что эта запись в данный момент изменяется дядяй Васей(ну или просто сказать,что мол занято).Вот такая реализация возможна???Или не стоит???
З.Ы. Пример взят из реальной жизни.Бухгалтерия у меня на работе работает именно по такому принципу.Как только открыл контрагента на одном компе и пытаешься открыть того-же на другом она и говорит,что мол на таком-то компе уже правят,а вам мол нельзя,подождите.
← →
jack128 © (2004-07-01 21:02) [25]
> Дык,по моему ИМХО это только для тех,кто разрешает править
> прямо в гриде.
да блин.. Ну какая разница в гриде - не в гриде!!! Главное в какой транзакции!!!!!
> своих программах я обычно не разрешаю править данные в гриде.Обычно
> это нажатие на кнопку "Изменить"-дальше открытие некой формы-ввод
> данных- и типа "Сохранить".В "Сохранить" обычно выполняется
> ХП и commit
и? Чтобы эти данные попали в грид нужно переоткрыть запрос, а это не есть гуд.
> Так вот,а теперь представьте ситуацию,предположим кто-то
> нажал на "Изменить" и пошел пить водку.Спустя некоторое
> время,на другом компе решили изменить ту же запись и тоже
> нажали "Изменить".Смысл в том,что-бы сказать юзеру,что эта
> запись в данный момент изменяется дядяй Васей(ну или просто
> сказать,что мол занято).Вот такая реализация возможна???Или
> не стоит???
и? Запрос на Update еще не выполнился, так что дядя Вася вполне может редактировать туже запись.
← →
jack128 © (2004-07-01 21:08) [26]
> Смысл в том,что-бы сказать юзеру,что эта
> > запись в данный момент изменяется дядяй Васей(ну или просто
>
> > сказать,что мол занято).
Да - поторился с ответом. Нужно при открытии диалога редактирования записи запустить так называемый "холостой" апдейт - запрос вида "update MyTable set field1 = fiedl1" тогда пока ты не закроешь текущую транзакцию дядя Вася не сможет изменить эту запись..
← →
GanibalLector © (2004-07-01 21:15) [27]2 jack128
>Нужно при открытии диалога редактирования записи запустить так называемый "холостой" апдейт - запрос вида "update MyTable set field1 = fiedl1" тогда пока ты не закроешь текущую транзакцию дядя Вася не сможет изменить эту запись..
О!!!А это уже вери гуд!!!
Спасибо!!!
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2004.07.25;
Скачать: [xml.tar.bz2];
Память: 0.53 MB
Время: 0.037 c