Interbase,CommitRetaining
1 отговора
85 прегледа
Interbase,CommitRetaining
Здравейте,
Отскоро работя над програмиране с бази данни. Затова, на този етап правя
някои експерименти, с опростен клиентски код и сърверски конструкции.
Използувам учебна InteBase 6.5 (5 clients). Не разполагам с реална мрежа
затова я имитирам. Сървера е сложен на измислен хост на моята машинка.
Той твърди,че е :
" InterBase SQL server for windows"
"TCP/I{ client support,Local client support"
За да имитирам мрежови ситуации, пускам две инстанции на едно и също
приложение.
Бях тръгнал да решавам конкретна задача, но налетях на междинен проблем,
който ме спря. Не се оправих веднага с документацията, затова ви моля за съвети.
Става въпрос за CommitRetaining() / Commit().
Използувам в прост пример :
TIBDataBase,TIBTransaction,
TIBDataSet query - за рекордсета
TDataSourec,TDBGrid - за визуализиране.
2-3 TDBedit
... и нищо друго.
Соурса е силно опростен, щото е експериметален. Някои от полетат се редактират
в грида, а две три в DBEdit. Имам буттон за прехвърляне на данните, и за фреш.
Нещо от сорта:
try {
.........................................
IBDataSet1->ApplyUpdates();
if( ! IBTransaction->InTransaction)
IBTRansaction->StartTransaction();
IBTransaction->CommitRetaining();
}
catch(...) {
IBTransaction->Rollback();
}
CommitReatining() ми съсздава объркването. Когато работя с две двете инстанции
и ги наблюдавм, очаквам след CommitRetaining(), промените направени от
първата инстанция да могат да се видят и във втората сле фреш или повторно
активиране на рецордсета. Това не става. Става едва след като ЗАТВОРЯ втората
инстанция и я пусна отново.
Когато използувма не CommitRetaining() a Commit(), нещата са наред, но затова
пък Commit() ми затваря сесията и контролите ми "жумват". Трябва да активирам
отново рекордсета.
2. Редактирам един запис в първата инстанция и го Post- вам. Премествам се на
друга запис. Втората инстанция не може да Update- записа, който преди това
първата е приключила " deadlock, concurent updates...". Сякаш се пазят буфери
с Pending Updates. Но къде ги тези буфери след като съм забранил
ChachedUpdates na рекордсета. Не виждам никъде контакт с характеристика
UpdateMode ( IsolationLevel).
Моля да ми кажете, къде евентуалоно греша в подхода или представата си.
Докато не реша този проблем, не трябва да мърдам по-нататък
Всъщност, конкретната задача, която бях тръгнал да решавам беше следната:
Когато едното приложение (било то на моя комп или на отдалечена станция)
направи някакви промени в данните, на моя комп те веднага да се видят.
И то в буквалния смисъл като на анимация. За определени случаи това е
много нужно. Чудя се как да го направа?
1. Откъм клиента периодично да фрешвам.
2. Или пък да чакам от сървера TIBEvents някакъв, иницииран от промяна.
Очаквам с нетърпение ваши препоръки. Благодаря предварително.
Отскоро работя над програмиране с бази данни. Затова, на този етап правя
някои експерименти, с опростен клиентски код и сърверски конструкции.
Използувам учебна InteBase 6.5 (5 clients). Не разполагам с реална мрежа
затова я имитирам. Сървера е сложен на измислен хост на моята машинка.
Той твърди,че е :
" InterBase SQL server for windows"
"TCP/I{ client support,Local client support"
За да имитирам мрежови ситуации, пускам две инстанции на едно и също
приложение.
Бях тръгнал да решавам конкретна задача, но налетях на междинен проблем,
който ме спря. Не се оправих веднага с документацията, затова ви моля за съвети.
Става въпрос за CommitRetaining() / Commit().
Използувам в прост пример :
TIBDataBase,TIBTransaction,
TIBDataSet query - за рекордсета
TDataSourec,TDBGrid - за визуализиране.
2-3 TDBedit
... и нищо друго.
Соурса е силно опростен, щото е експериметален. Някои от полетат се редактират
в грида, а две три в DBEdit. Имам буттон за прехвърляне на данните, и за фреш.
Нещо от сорта:
try {
.........................................
IBDataSet1->ApplyUpdates();
if( ! IBTransaction->InTransaction)
IBTRansaction->StartTransaction();
IBTransaction->CommitRetaining();
}
catch(...) {
IBTransaction->Rollback();
}
CommitReatining() ми съсздава объркването. Когато работя с две двете инстанции
и ги наблюдавм, очаквам след CommitRetaining(), промените направени от
първата инстанция да могат да се видят и във втората сле фреш или повторно
активиране на рецордсета. Това не става. Става едва след като ЗАТВОРЯ втората
инстанция и я пусна отново.
Когато използувма не CommitRetaining() a Commit(), нещата са наред, но затова
пък Commit() ми затваря сесията и контролите ми "жумват". Трябва да активирам
отново рекордсета.
2. Редактирам един запис в първата инстанция и го Post- вам. Премествам се на
друга запис. Втората инстанция не може да Update- записа, който преди това
първата е приключила " deadlock, concurent updates...". Сякаш се пазят буфери
с Pending Updates. Но къде ги тези буфери след като съм забранил
ChachedUpdates na рекордсета. Не виждам никъде контакт с характеристика
UpdateMode ( IsolationLevel).
Моля да ми кажете, къде евентуалоно греша в подхода или представата си.
Докато не реша този проблем, не трябва да мърдам по-нататък
Всъщност, конкретната задача, която бях тръгнал да решавам беше следната:
Когато едното приложение (било то на моя комп или на отдалечена станция)
направи някакви промени в данните, на моя комп те веднага да се видят.
И то в буквалния смисъл като на анимация. За определени случаи това е
много нужно. Чудя се как да го направа?
1. Откъм клиента периодично да фрешвам.
2. Или пък да чакам от сървера TIBEvents някакъв, иницииран от промяна.
Очаквам с нетърпение ваши препоръки. Благодаря предварително.
Re: Interbase,CommitRetaining
Първо кажи какви са ти параметрите на транзакцията... Може би в твоя случай е най-добре да я направиш ReadCommited.
Абе изобщо управлението на транзакциите не е съвсем тривиална работа. Може би най-същественият недостатък на IBX е работата с дълги транзакции, т.е. START, SELECT,.... UPDATE, COMMIT, като между извличането на данните и ъпдейтването им може да мине голям период от време. Правилният начин би трябвало да е SELECT,.... START, UPDATE, COMMIT. Също така ако можеш да ползваш commit вместо commit retainnig е по-добре. Commit retaining запазва контекста, но на сървъра остават заети ресурси, което при продължителна работа си се натрупва...
Във FIBPlus ако си обърнал внимание компонентите имат две отделни транзакции - за извличане на данни и за ъпдейтването им и това ти дава възможност да постигнеш този втория модел с кратките транзакции. А и по дебелите книги си пише, че транзакциите трябва да бъдат възможно най-кратки :)
Значи вземи да прочетеш за параметрите на транзакциите в документацията на InterBase за да разбереш заради това ли не си виждаш записите... Предполагам, че в приложението си имаш само една транзакция, ама ако са повече - виж правилната ли commit-ваш :)
2. Редактирам един запис в първата инстанция и го Post- вам. Премествам се на
друга запис. Втората инстанция не може да Update- записа, който преди това
първата е приключила " deadlock, concurent updates...". Сякаш се пазят буфери
с Pending Updates. Но къде ги тези буфери след като съм забранил
ChachedUpdates na рекордсета. Не виждам никъде контакт с характеристика
UpdateMode ( IsolationLevel).
Когато един запис бъде променен в контекста на някоя транзакция той остава заключен за другите транзакции (ако изобщо се вижда от тях - зависи) до приключването й. При опит да бъде променен или изтрит от друга транзакция получаваш deadlock. Заключването става на сървъра, управлява се от InterBase-а и няма нищо общо с CachedUpdates.
Всъщност, конкретната задача, която бях тръгнал да решавам беше следната:
Когато едното приложение (било то на моя комп или на отдалечена станция)
направи някакви промени в данните, на моя комп те веднага да се видят.
И то в буквалния смисъл като на анимация. За определени случаи това е
много нужно. Чудя се как да го направа?
1. Откъм клиента периодично да фрешвам.
2. Или пък да чакам от сървера TIBEvents някакъв, иницииран от промяна.
По принцип за това служи POST_EVENT + IBEvents, но има малко проблеми с тях. Виж статийката долу. Едно от решенията е да ползваш 3-tier/n-tier архитектура, но това не винаги е оправдано. Виж как става с IBEvents, пък ако не ти върши работа ще измислиш нещо друго
[url=[линк]]People's wisdom versus IBX author's conservatism?[/url]
Do you have problems with InterBase event alerters?
Абе изобщо управлението на транзакциите не е съвсем тривиална работа. Може би най-същественият недостатък на IBX е работата с дълги транзакции, т.е. START, SELECT,.... UPDATE, COMMIT, като между извличането на данните и ъпдейтването им може да мине голям период от време. Правилният начин би трябвало да е SELECT,.... START, UPDATE, COMMIT. Също така ако можеш да ползваш commit вместо commit retainnig е по-добре. Commit retaining запазва контекста, но на сървъра остават заети ресурси, което при продължителна работа си се натрупва...
Във FIBPlus ако си обърнал внимание компонентите имат две отделни транзакции - за извличане на данни и за ъпдейтването им и това ти дава възможност да постигнеш този втория модел с кратките транзакции. А и по дебелите книги си пише, че транзакциите трябва да бъдат възможно най-кратки :)
Значи вземи да прочетеш за параметрите на транзакциите в документацията на InterBase за да разбереш заради това ли не си виждаш записите... Предполагам, че в приложението си имаш само една транзакция, ама ако са повече - виж правилната ли commit-ваш :)
2. Редактирам един запис в първата инстанция и го Post- вам. Премествам се на
друга запис. Втората инстанция не може да Update- записа, който преди това
първата е приключила " deadlock, concurent updates...". Сякаш се пазят буфери
с Pending Updates. Но къде ги тези буфери след като съм забранил
ChachedUpdates na рекордсета. Не виждам никъде контакт с характеристика
UpdateMode ( IsolationLevel).
Когато един запис бъде променен в контекста на някоя транзакция той остава заключен за другите транзакции (ако изобщо се вижда от тях - зависи) до приключването й. При опит да бъде променен или изтрит от друга транзакция получаваш deadlock. Заключването става на сървъра, управлява се от InterBase-а и няма нищо общо с CachedUpdates.
Всъщност, конкретната задача, която бях тръгнал да решавам беше следната:
Когато едното приложение (било то на моя комп или на отдалечена станция)
направи някакви промени в данните, на моя комп те веднага да се видят.
И то в буквалния смисъл като на анимация. За определени случаи това е
много нужно. Чудя се как да го направа?
1. Откъм клиента периодично да фрешвам.
2. Или пък да чакам от сървера TIBEvents някакъв, иницииран от промяна.
По принцип за това служи POST_EVENT + IBEvents, но има малко проблеми с тях. Виж статийката долу. Едно от решенията е да ползваш 3-tier/n-tier архитектура, но това не винаги е оправдано. Виж как става с IBEvents, пък ако не ти върши работа ще измислиш нещо друго
[url=[линк]]People's wisdom versus IBX author's conservatism?[/url]
Do you have problems with InterBase event alerters?