Jakie techniki stosować do połączenia aplikacją Delphi7 z Firebirdem

0

Witam,
//Mały wstęp.
Od razu przejdę do rzeczy.
Piszę sobie aplikację w Delphi7 i używam IBXów do łączenia z bazą na Firebirdzie2.1.
W bazie są tabele z kluczami własnymi,obcymi; widokami do spisów z kilku tabel i do list i zestawień ,wyzwalacze z generatorami do auto-numerowania i niektóre procedury do tego co mi potrzeba.
Po stronie projektu Delphi są formularze do wypełniania danych, przykładowy formularz zawiera dbGrida i kontrolki IBX do edytowania danych i poruszania się po zbiorze danych.
Jest formularz typu DataModule na nim IBDatabase,IBTransaction(domyślny),IBQuery z Datasetami i IBUpdate-mi (no chyba że zapytanie o widok to bez IbUpdate-a)
W komponencie IBDatabase user SYSDBA itd..standardowo wszystko "gra i śmiga" (nawet inserty i update na jednym IBtransaction).
Problem zaczyna się jeśli chcę się połączyć z dwóch komputerów do jednej bazy.
Czasem połączą się i gdy dojdzie do edytowania tej samej tabeli to wyświetla informacje o deadlokach i program zacina się.
Czasem od razu aplikacja wyświetli AccesViolation z numerkiem jakimś.
Niedawno dowiedziałem się,że Firebird od wersji 2.0 użytkownik SYSDBA może połączyć się tylko raz.
//treść tematu
Ale chcę pozbyć kłopotów z IBXami przy pracy klient-serwer wielostanowiskowej
-jak używam IBTable to komponent pobiera zbiór danych i trzyma "prawie na wyłączność" dane i jak drugi użytkownik chce coś zrobić z tą samą tablicą to aż strach pomyśleć.
Z IBQuery jest prościej ale jeśli dołączymy IBUpdate i operujemy na zbiorze to sypie deadlokami i wychodzi na to samo.
Więc myśle tak że Tabelę do DBGrida odczytam z bazy z widoku.(wtedy nawet nie będę musiał wstawiać kontrolek lookup)
Natomiast do Insertów,Updatów (delete nie stosuje :-) wykorzystam StoredProcedure w bazie.
Pytanie jest takie czy transakcje dla tych Insertów i Updatów kontrolować wtedy w Delphi czy w Firebirdzie?

0

Niedawno dowiedziałem się,że Firebird od wersji 2.0 użytkownik SYSDBA może połączyć się tylko raz.

Załóż innego użytkownika i przetestuj, sam działam na firebirdzie i nigdy nie miałem takiego przypadku, ja łączę się za pomocą założonego Usera

0

Dla mojej aplikacji zmiana mechanizmów logowania i używania chociażby ID_USER-a to sporo roboty.
Pozttym muszę się dowiedzieć czy nazwa usera może mieć swój klucz główny. potem procedury zmiany haseł i role do każdej tablicy widoku procedury wyzwalacza.......:-|

0

@piusik za używanie IBTable do baz klient-serwer powinni dawać dożywotni zakaz pisania programów bazodanowych :]

Szczerze to ja używam podobnego połączenia (FB+IBX) i deadlock zdarzył mi się zaledwie parę razy. U większości klientów nigdy go nie było. http://www.firebirdfaq.org/faq151/ Nie mniej jednak:

This is a normal event in database world and your application should be ready to deal with it.

Sądzę, że masz coś skopane w zarządzaniu transakcjami w swoim systemie skoro ten problem ujawnia się tak często (przecież mało kiedy zdarza się, że dwóch użytkowników w tym samym czasie chce zmienić np. tego samego kontrahenta). Pamiętaj, że zaleca się aby transakcje były maksymalnie krótkie. Im dłuższy jest czas od Transaction->Start() do Transaction->Commit tym większa szansa na powstanie deadlocka. Ja tam Commituję do bazy po każdym poście. Dzięki czemu inni użytkownicy mają możliwość zobaczenia prawie natychmiast co się dzieje.

piusik napisał(a):

Dla mojej aplikacji zmiana mechanizmów logowania i używania chociażby ID_USER-a to sporo roboty.
Pozttym muszę się dowiedzieć czy nazwa usera może mieć swój klucz główny. potem procedury zmiany haseł i role do każdej tablicy widoku procedury wyzwalacza.......:-|
Ale chyba nie za bardzo rozumiesz o czym kolega mówił. Jemu chodziło o użytkownika do bazy Firebird. Co ma nazwa SYSDBA do klucza głównego? Co do uprawnień to zakładając tabelę/procedurę można dodać polecenie

grant on table to my_user

i po kłopocie
Ewentualnie podczas tworzenia bazy danych z programu można to załatwić 1 procedurką składowaną i nadać uprawnienia do wszystkich obiektów w bazie Twojemu użytkownikowi.

0

pytanie podstawowe - masz zainstalowany serwer FB/IB czy łączysz się do bazy embedded? Bo jak do embedded to to nie jest baza do pracy wielostanowiskowej.

BTW DeadLock (o ile nie jest założony celowo) to jest błąd w logice aplikacji (czyli problem z programistą i nieznajomość tematu) a nie problem z bazą

piusik napisał(a):

Dla mojej aplikacji zmiana mechanizmów logowania i używania chociażby ID_USER-a to sporo roboty.
Pozttym muszę się dowiedzieć czy nazwa usera może mieć swój klucz główny. potem procedury zmiany haseł i role do każdej tablicy widoku procedury wyzwalacza.......:-|

chyba nie do końca wiesz o czym piszesz i o czym piszą inni

0

Tak, nie do końca znam się na organizacji użytkowników w bazie bo tym się jeszcze nie zajmowałem, wszystko do tej pory było na SYSDBA,
Co do transakcji to jest jedna domyślna dopięta do komponentu ibdatabase, jak dodałem inne do obsługi np, zapisu w tabeli to się zaczęły błędy.
I jeszcze jedno nie napisałem że mam problem z bazą tylko pytam doświadczonych w temacie użytkowników o podpowiedzi i sugestie.
pozdrawiam.

1

no widzisz tylko, że teraz to jest tzw. rzeźbienie w gównie - bardzo ciężko jest poprawić coś co jest ukończone bez przepisywania znacznej części kodu. Piszesz, że używasz IBTable - należało by się ich pozbyć. Co do samych transakcji to najpierw trzeba zrozumieć po co one są i jak działają aby poprawnie ich używać. Trudno jest cokolwiek doradzić na podstawie samego opisu. U Ciebie problem jest na tyle rozległy, że trudno będzie cokolwiek doradzić bez zobaczenia i przeanalizowania całości kodu. Jak już pisałem niechciane DeadLocki to w 99% przypadków niewiedza i złe zaprojektowanie aplikacji. Takich błędów nie wyeliminujesz szybko ani prosto.

Co do AccesViolation natomiast to, o ile nie są to błędy w kontrolkach IBX, nie mają związku z bazą jako taką - AccesViolation to próba odwołania się do nieistniejących obiektów (np. przed ich stworzeniem albo po ich usunięciu).

0
piusik napisał(a):

Co do transakcji to jest jedna domyślna dopięta do komponentu ibdatabase, jak dodałem inne do obsługi np, zapisu w tabeli to się zaczęły błędy.
To akurat w niczym za bardzo nie przeszkadza. Nie powinno być powodem walenia się programu, że mamy 1 globalną transakcję.

piusik napisał(a):

I jeszcze jedno nie napisałem że mam problem z bazą tylko pytam doświadczonych w temacie użytkowników o podpowiedzi i sugestie.
Niestety tak na odległość nikt Ci nie pomoże. Musiałbyś poszukać kogoś kto pisał takie aplikacje i pokazać mu kod, opowiedzieć jaka architektura.

Tak przy okazji to czemu korzystasz z wersji 2.0? Najlepiej by było przejść na wersję 2.5, ewentualnie najnowszą 2.1.

No i nie odpowiedziałeś na pytanie kolegi:

abrakadaber napisał(a):

pytanie podstawowe - masz zainstalowany serwer FB/IB czy łączysz się do bazy embedded? Bo jak do embedded to to nie jest baza do pracy wielostanowiskowej.

0

Używam serwera Firebird2.1 superserwer. Napisałem, że dowiedziałem się że od wersji 2.0 można połączyć się SYSDBA tylko z jednego miejsca.
Nie korzystam z IBtable tylko z IBQuery + IBUpdate.
na razie odpuściłem sobie pracę wielostanowiskową. Rozważam "zdemontowanie" całej warstwy aplikacji i procedur w bazie aż do gołych tabel i trigerów i napisanie od nowa wszystkich mechanizmów.
Wiąże się to od nowa z setkami godzin testowania i "dopieszczania" kodów SQL, ObjectPascala i niektóre raporty do "renowacji" ;-)

0
piusik napisał(a):

Używam serwera Firebird2.1 superserwer. Napisałem, że dowiedziałem się że od wersji 2.0 można połączyć się SYSDBA tylko z jednego miejsca.

no popatrz mam FB 2.5 i można się na SYSDBA łączyć ile razy Ci się podoba. BTW nigdzie w dokumentacji do FB nie znalazłem wzmianki o takim ograniczeniu

0

Wyczytałem tutaj:
https://sites.google.com/site/firebirdidelphi/firebird/firebird-2-0#TOC-Bezpieczniejszy-tryb-serwisowy
lecz może to dotyczyć tylko trybu serwisowego...

0

@piusik jeśli w bazie masz dużo procedur i triggerów to w tym może leżeć wina. Mój współpracownik dostał w spadku taki moduł. Złe zarządzanie transakcjami powodowało to, że niektóre procedury wywalały się na deadlockach. Po naprawie zarządzania transakcjami w programie wszystko jak ręka odjął.

Co do połączeń to sam używam tak samo wersji 2.5 jak i 2.1 i jeszcze nie miałem takiego ograniczenia, więc to na pewno nie tu leży problem.

piusik napisał(a):

lecz może to dotyczyć tylko trybu serwisowego...
Moim zdaniem jeśli to by było jakieś ograniczenie po stronie serwera to w ogóle nie dałbyś rady się połączyć i miałbyś rzucony wyjątek podczas próby nawiązania połączenia. Szukaj w skopanej architekturze programu.

1
piusik napisał(a):

Wyczytałem tutaj:
https://sites.google.com/site/firebirdidelphi/firebird/firebird-2-0#TOC-Bezpieczniejszy-tryb-serwisowy
lecz może to dotyczyć tylko trybu serwisowego...

nie może tylko właśnie tego konkretnego trybu dotyczy a nie normalnej pracy

0

Dodam tylko że wcześniej połączenie było tylko z jednego komputera i na nim był zainstalowany serwer (mógł nawet pracować w trybie embedded) i nie było problemów z dedlokami lub brakiem możliwości połączenia do danych, teraz zaszła potrzeba dostępu z 3 stanowisk i się zaczęły schody.
No nic, prawdopodobnie będę musiał znaleźć źródło wiedzy na temat metod dostępu i pracy na danych w trybie wielostanowiskowym i napisać od nowa.

0
piusik napisał(a):

No nic, prawdopodobnie będę musiał znaleźć źródło wiedzy na temat metod dostępu i pracy na danych w trybie wielostanowiskowym i napisać od nowa.
Jak dla mnie musisz po prostu poczytać jak używać transakcji i tyle. W zasadzie nic trudnego.

0

Transakcje w IBX-ach są trochę innym tworem niż to co się pisze w literaturze...
Mając podpiętą jedną domyślną transakcję to ona ogarnia wszystko praktycznie sama, jedynie co mogę zrobić to odczytać czy aktualnie jest w trakcie wykonywania transakcji i zrobić Commit lub CommitRetaining z Rollback już potrafią dziać się dziwne rzeczy :-)
Wkładając drugi komponent typu IBtransaction i pruba operacji na tej samej bazie kończy się fiaskiem :-)
Więc albo nie do końca chyba potrafię "czarować" w tych IBX-ach albo pewne mechanizmy nie są zgodne z przeznaczeniem docelowym. Dodam że IBexpert potrafi robić kilka transakcji jednocześnie bez błędów więc jest to możliwe :-)
Może czas przesiąść się na Zeosy:-)

0

Generalnie nigdy nie miałem takich objawów jak piszesz. Czy to Commit/CommitRetaining czy Rollback/RollbackRetaining system się zachowuje normalnie. To samo tyczy się drugiej transakcji. Czy aby na pewno po każdym Post masz dany Commit?

0

Może, moje perypetie są spowodowane że w d7 IBXy nie do końca są kompatybilne z FB2.1 ale nie chcę dalej dywagować na temat IBXów.

Chodzi mi generalnie czy niżej opisana koncepcja jest odpowiednia?
Tabela z danymi odczytywana jest za pomocą IBquery (bez IBUpdate) z widoku z bazy FB w trybie readonly.
Inserty,Update i prawie nigdy stosowane Delete Wywoływane za pomocą IBQuery do procedur z parametrami w FB.
Dopiero Procedura z FB sprawdza dodaje uaktualnia itp...
Po wykonaniu procedury znowu odczytuje sobie IBQuery z widoku do tabeli.

Na to na celu odrzucenie operacji na "żywych" danych w komponentach takich jak:
IBTable (oczywiście już nie stosowanych obecnie)
oraz IBQuery + IBUpdate

0
piusik napisał(a):

Może, moje perypetie są spowodowane że w d7 IBXy nie do końca są kompatybilne z FB2.1 ale nie chcę dalej dywagować na temat IBXów.
Powiem Ci, że to nie jest wina IBX'ów.

piusik napisał(a):

Chodzi mi generalnie czy niżej opisana koncepcja jest odpowiednia?
Tabela z danymi odczytywana jest za pomocą IBquery (bez IBUpdate) z widoku z bazy FB w trybie readonly.
Inserty,Update i prawie nigdy stosowane Delete Wywoływane za pomocą IBQuery do procedur z parametrami w FB.
Dopiero Procedura z FB sprawdza dodaje uaktualnia itp...
Po wykonaniu procedury znowu odczytuje sobie IBQuery z widoku do tabeli.
Znam te rozwiązanie i jak dla mnie jest straszne, o wiele więcej pisania niż w podejściu klasycznym z wykorzystaniem IBDataSetów. Musisz poczytać o tym jak się robi "updatable views" oraz jak w nich zarządzać transakcjami. Ale kolejny raz powtórzę, że dla mnie tu siedzi problem. Być może program działa cały czas na niezatwierdzonej transakcji i tak będzie się wtedy działo.

piusik napisał(a):

Na to na celu odrzucenie operacji na "żywych" danych w komponentach takich jak:
IBTable (oczywiście już nie stosowanych obecnie)
oraz IBQuery + IBUpdate
Ja zawsze stosuję IBDataSet (łączy w sobie obydwa komponenty) i jakoś nie widzę z tym problemów. Zwłaszcza, że całość zamknięta jest w oddzielnym unicie a okna tylko wyświetlają dane.

1 użytkowników online, w tym zalogowanych: 0, gości: 1