DB szinkronizálás web service-szel

Fórumok

Hello,

Két tetszőleges db között szeretnék rekordokat szinkronizálni web service segítségével. Kizárólag gép-gép között kell kommunikálni, megfelelő authentikáció után.
Most ásom bele magam a projekt ezen részébe. Eddig végigolvastam néhány tutorialt (jax-ws,jax-rs,apache cxf stb.), de néhány megvilágosító gondolat nem ártana.
Szóval adott a szerver oldalon egy Users tábla, aminek van egy Dao osztálya. A kliens oldalon ugyanez megvan, másik db, Users tábla Dao osztály. Ha felvértezem a szerveren lévő Dao osztályt a megfelelő annotációkkal (WebService, WebMethod stb.) és regisztrálom a szolgáltatást, akkor a kliens képes lesz elkérni tőle egy Users típusú objektumot és mondjuk az update-elni a saját táblájába ?
(Nyilván a másik irányba is szükség van erre.)
Erre kellene nagyjából egy kőbaltás megoldás,amit én is megértek :).
Köszönöm!

Hozzászólások

szerintem erre nem fogsz így "kőbaltás", egyszerű, használható és működőképes megoldást "for dummies" leakasztani a falról. ha létezne, már rég mindenki ezt használná.

az alapvető koncepcionális sarokkő az egészben, hogy ha az alkalmazás replikálja az adatokat, akkor az alkalmazás írójának kell végiggondolnia, hogy milyen konzisztenciát igényel az alkalmazás, és ezt milyen módszerekkel tudja a kigondolt megoldás biztosítani. az nem megy, hogy "ezt valaki más gondolja végig helyettem".

az egyik kiinduló kérdés pl., hogy melyik irányba megy a replikálás. master-master megoldásra vágyunk, vagy jó a master->slave is. mindkettőnek előnyei és hátrányai is vannak.

Multimaster-re is létezik szép elmélet, de én kutatási projekten kívül nagyon meggondolnám, hogy hozzányúlnék-e ilyesmihez. Az üzemeltetésnek valószínűleg nagyon fontos, hogy bármikor gondolkodás nélkül, a saját eszközeit használva rögtön meg tudja mondani, melyik a master adat, és onnan újra tudja indítani a terítést.

Én a tömegesen (kötegelten) is működtethető terítésben tanultam meg hinni. A WS tudjon tömbökkel is dolgozni, és a ciklusok, amelyek a tömböket összeállítják ill. szétdobják, a szélekhez (az adatbázisokhoz) a lehető legközelebb legyen. Egy db felhasználót pedig forrásoldali (master oldali) verziószám és egy teljes lenyomat írjon le az üzenetben (ne diff).

... Ah, megint egy hónapos hozzászólásra sikerült reagálnom. Sebaj.

A kliensprogramnak a szerver nélkül (tehát offline) is működnie kell? Mert ha nem, akkor a kliens oldalra nem kell adatbázis, a műveleteket egyből a szerveren lehet végezni, és sokkal egyszerűbb minden.

Ha offline műveletek is vannak, akkor a több felhasználó műveletei között lehetnek ellentmondásosak is, ezek kezelése pedig nagyon nem piskóta viszonylag egyszerű esetekben sem. Tehát ezt a legjobb elkerülni.

Itt két külön rendszerről van szó, tehát kell két db. Igen, lehet offline működés is. Alapvetően a következő a helyzet:

db1: valaki létrehoz egy rekordot
db2: itt a kliens megnézi (amikor felébred) hogy a másik oldal él e és van e szinkronizálandó adat. ha van akkor megteszi amit kell illetve ha kliens oldalon volt olyan változás amit át kell tenni db1-be, akkor megteszi azt is.

Kb. ennyi.

Akkor tehat master-master replikaciot kell gyartanod.

Mi van a collision-nel? Mi tortenik a replikacio folyaman? Van-e blokkolas mindket oldalon a replikacio idejere (ne keletkezzen addig uj adat, amig az aktualis replikacio le nem zajlott)?

Mi van az osszekapcsolt objektumokkal? Van cascade valahol? Ha igen, ezt hogy akarod lekezelni a replikacioban?

Ezek olyan kerdesek, amikre mindenkepp valaszt KELL adnod, mielott BARMIT csinalnal. Vegig kell gondolni a replikacio folyamatat, ez nem egy konyvtarszinkronizalas, hogy majd legfeljebb megegyszer nekifutunk.
--

Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal 

"Akkor tehat master-master replikaciot kell gyartanod."
Tulajdonképpen igen. db1 bizonyos szempont szerint magasabb prioritással bír. Ha ott módosult egy adat, akkor az kerül át a db2-re függetlenül attól, h db2-n változott e előtte vagy közben.

"Mi van a collision-nel? Mi tortenik a replikacio folyaman?"
collision esetén lesz rá szabály, de alap eset h a db1-en történt változás az erősebb.

"Van-e blokkolas mindket oldalon a replikacio idejere (ne keletkezzen addig uj adat, amig az aktualis replikacio le nem zajlott)?"
Lehet jelentősége, de nem érzem problémának jelenleg mivel mindkét helyen gyakorlatilag ugyanazon adatok egy példánya van jelen.
Vannak táblák, ahova pedig csak egyik oldalról kerül be adat, a másik felolvassa azt, de visszafele már nem gyárt rekordot.

"Mi van az osszekapcsolt objektumokkal? Van cascade valahol? Ha igen, ezt hogy akarod lekezelni a replikacioban?"
Nem lesz cascade, de idáig még nem jutottam.

"Ezek olyan kerdesek, amikre mindenkepp valaszt KELL adnod, mielott BARMIT csinalnal. Vegig kell gondolni a replikacio folyamatat, ez nem egy konyvtarszinkronizalas, hogy majd legfeljebb megegyszer nekifutunk."

Teljesen igaz. Volt már néhány hasonló projektem, de ott nem web service-szel ment a dolog. Most tartok épp az _alapos_ tervezésnél.
Sikerélményem is van. Gyártottam egy web service-t illetve egy kliens, ami elkér egy User típusú objektumot a szolgáltatástól, megváltoztatja egy attribútumát, majd egy másik metódussal perzisztálja.
Működött :D.

"Lehet jelentősége, de nem érzem problémának jelenleg"

Ez nem erzes kerdese. Amennyiben van a barmely db oldalan barmilyen ertelemben adatbevitel kulso forrasbol (user input, bulk import, masik webservice, etc.), mely erinti a replikacio altal erintett tablakat, abban az esetben a replikacio idejere blokkolnod kell az adatbevitelt, vagy legalabbis delayezni (berakni egy modositasi queue-ba). Nyilvan te latod at a folyamatot, hogy hol-mi modosulhat, viszont azt nem lehet megengedni, hogy a replikacio folyamataban egy user input esetleg invalidaljon egy replikacio alatt levo erteket (legalabbis, ha nem hobbybol replikalsz. A replikacionak by def az az ertelme, hogy lehetoseg szerint mindket helyen megegyezzenek az adatok).

A cascade ugyanez. Ha az adatbazisban van valahol valamiert cascade, akkor nem teheted meg, hogy a replikacioban ezt nem kezeled le. Itt is kineznek a blokkolasok elso korben, masodik korben
--

Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal 

Nem hobby replikálás lesz. Azon vagyok, hogy ne az legyen. Egyelőre minden részletét nem tudtam megtervezni, ezért egyelőre csak körvonalai vannak a megvalósításnak.
Visszatérve a blokkolásra. Lesz módosítási queue. Annyiszor módosít, ahányszor akar, időben a legutolsó lesz az aktuális.

"Nyilvan te latod at a folyamatot, hogy hol-mi modosulhat, viszont azt nem lehet megengedni, hogy a replikacio folyamataban egy user input esetleg invalidaljon egy replikacio alatt levo erteket (legalabbis, ha nem hobbybol replikalsz. A replikacionak by def az az ertelme, hogy lehetoseg szerint mindket helyen megegyezzenek az adatok)."

Szó nincs róla, hogy valaki belepiszkálna. Mivel módosítási sorról van szó, oda egy trigger rakja be a módosított rekordot, amihez a usernek nem sok köze van. Bulk import nem játszik, másik web service nem lesz, ami ide beletúrhat.
Tudom, hogy sok helyzettel kell számolni tervezési szempontból, igyekszem mindet végigvenni, amiről semmit nem tudok azt meg megkérdezni.

Az user input csak egy pelda volt. En a helyedben a modositasi sort (ha magat a sort replikalod) blokkolnam a replikacio idejere, nehogy veletlenul a trigger ugy gondolja, hogy akkor most ide teszunk egy ixet.
--

Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal 

a replikacio idejere blokkolnod kell az adatbevitelt, vagy legalabbis delayezni (berakni egy modositasi queue-ba) [...] azt nem lehet megengedni, hogy a replikacio folyamataban egy user input esetleg invalidaljon egy replikacio alatt levo erteket

Nem feltétlenül; sok helyen elég az "eventual consistency".

nem lenne egyszerűbb a szükséges táblák tartalmát adatbázis szinten replikálni a 2 branch között?

Majdnem pont ugyanezt csináltunk nemrég, csak nekünk 3 táblára egyirányú szinkronizáció kellett, 1 táblára 2 irányú.
Az egyik rendszert SOAP-on értjük el, a másikhoz van ODBC adatbázis kapcsolat. .NET-ben csináltuk, mert az kellett, de Java-ban kb ugyanez a megoldás, kb ugyanekkora szopással.
Persze a szinkronizációs logikát le kellett implementálni, mert a 2-irányúnál sok mindenre kellett figyelni, de amúgy nem volt nagy kunszt, csak alaposan át kell gondolni, hogy minden lehetséges esetet lefedjen a kód. (ha törlik a B táblából, töröljük-e A-ból, ha különbözik a kettő, melyiket frissíted melyikre, stb.)

A te esetedben lehet h egyszerűbb lenne a két adatbázis rávenni replikációra, oldják meg maguktól, persze megfelelő motor is kell hozzá, én nem feltétlenül saját webservice-el futnék neki. Ha a két tábla egyforma teljesen, akkor egy megfelelően bebiztosított adatbázis kapcsolatot kipublikálhatnál a szerveren, és akkor a kliensnek két táblát kell összemazsoláznia, akár JDBC szinten is, vagy JPA/Hibernate esetén equals() segítségével.

Na pá

Szeretném ezt alkalmazás szintjén megoldani. Elképzelhető, hogy később más rendszer(ek) is használnák ezt a szolgáltatást és egyszerűbb lenne nekik azt mondani, h itt ezt a metódust kell hívni ezekkel a paraméterekkel.

Én semmiképp se a DAO osztályt annotálnám, több okból sem, de főleg azért, mert a DAO osztály nem erre való. Lehet csinálni *WebService osztályt, ami fel van szépen annotálva, és abból tovább lehet hívni a DAO-ba.

Kőbaltás megoldást nem tudok, de nyilván ki kell találni, hogy mi a stratégia a szinkronizáció során, hogyan lehet érzékelni/jelezni a változásokat, és hogy hogyan vigyük át a változásokat egyik adatbázisból a másikba.

Én beleolvasnék valamilyen elosztott rdbms vagy cluster dokumentációba, hátha nyújt valamilyen ötletet.

Liferay-ben is van db replikáció, igaz egyirányú, nézd meg esetleg.
--
Gábriel Ákos