[Delphi+FB] Dziwny problem z replikacją

0

Cześć, mój program jest oparty o Firebirda i wyposażony w mechanizm replikacji, który jednak mnie samego zaskakuje. Otóż wg algorytmu, jakby nie patrzeć wszystko powinno działać, postaram się wyjaśnić cały problem:

Są 2 tabele:

Transakcje(ID, .......) gdzie ID to Primary Key
POS(ID, ID_TRANS, ....), gdzie ID to Primary Key, a ID_TRANS to FOREIGN Key wskazujący oczywiście na ID z tabeli Transakcje

I teraz tak, załóżmy, że są 2 lokale podłaczone do tej samej bazy danych, ale jeden z nich traci połączenie.

Ten, który ma połączenie przeprowadza sobie jakąś transakcję(mówiąc transakcja mam na myśli, że przyszedł klient i coś kupił), skutkiem czego jest jeden wpis w tabeli TRANSAKCJE i kilka wpisów w tabeli POS.

Lokal, który utracił połączenie przełączył się na bazę awaryjną i na niej może pracować z pewnymi ograniczeniami. Jednak też może przeprowadzić transakcje. I załóżmy, że przeprowadził jakieś - co znowu skutkuje wpisami w tabeli TRANSAKCJE i POS, a także w specjalnej tabeli REPL_CHANGES. Do niej wpisywana jest nazwa tabeli, w której zaszła zmiana(w tym wypadku TRANSAKCJE i POS), a także ID pierwszego rekordu, który został dodany.
(Ogólnie struktura wygląda krótko mówiąc podobnie: ID, TABLE_NAME, FIRST_ID, gdzie first_ID to ID dodanego rekordu). Jeśli będą dodane 2 wpisy w tabeli TRANSAKCJE, to w REPL_CHANGES będzie tylko jedna taka informacja.

W każdym razie, teraz, gdy lokal odzyskuje połączenie z bazą główną, musi się zreplikować.

I to jest robione na takiej zasadzie(na konkretnym przykładzie)
Program sprawdza bazę awaryjną, tabelę REPL_CHANGES - pobiera sobie z niej dane
Następnie znajduje pierwszy rekord w tej tabeli, gdzie pole TABLE_NAME = 'TRANSAKCJE'

Teraz sprawdza ostatnie ID(MAX(ID)) w tabeli TRANSAKCJE w bazie głównej. Do tej liczby dodaje przykładowo 30 i wynikiem tego działania jest nowe ID rekordu w tabeli TRANSAKCJE w bazie AWARYJNEJ.

Tzn. zostaje zwiększone ID każdemu rekordowi w bazie awaryjnej w odpowiedniej tabeli. Skutkiem tego jest to, że baza awaryjna z główną się nie gryzą i można bez problemu wstawiać rekordy.

Ale skoro zmieniam ID w tabeli TRANSAKCJE, muszę też zmienić ID_TRANS w tabeli POS - jednak to jest(powinno być) robione przez Firebirda, gdyż mam na tym polu UPDATE_RULE = CASCADE

I tu się pojawia dziwny problem.
Kiedy pomiędzy poszczególne instrukcje w kodzie replikacji dam showMessage z jakimś tekstem, co dokładnie w tej chwili jest robione, jakie zapytania itd, to wszystko jest ok. Ale gdy pozbędę się ShowMessage, to wtedy po bezbłędnej replikacji tabeli TRANSAKCJE, podczas replikacji tabeli POS dostaję błąd: "violation of FOREIGN KEY constraint FK_POS_1 on table POS. Foreign key reference target does not exist" - FK_POS_1 to oczywiście pole ID_TRANS

Czyli tak, jakby ID transakcji się zupdateowało, a ID_TRANS w posie pozostało bez zmian.

Pomocy, bo zaraz zwariuję.

[DOPISANE]
Zamiast showMessage, w jednym miejscu(po update idków) umieściłem: sleep(1000) i jak na razie widać, że to działa

0
  1. wybiera się narzędzie do problemu a nie na siłe stara się coś zaadoptować - postgresql + slony i byś miał z głowy
  2. jak już dałeś ciała na etapie projektowania i wyboru narzędzi to opłaca się poszukać
    http://fibre.sourceforge.net/
    http://replicator.daffodilsw.com/
0
Misiekd napisał(a)
  1. jak już dałeś ciała na etapie projektowania i wyboru narzędzi to opłaca się poszukać

Niestety, mimo usilnych starań, nie miałem wpływu na wybór DBMS. A gdybym miał, to wybrałbym MSSQLa ;)

A co do narzędzi to przetestowałem ich swego czasu sporo. Jednak jeśli już coś działało mniej więcej tak jak powinno, to było poważnie płatne. Mój przełożony nie chciał się na to zgodzić... Cóż... więc ja zarobiłem ;)

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