EJB 3 - zapis przez zabrudzenie

0

witam,
mam nastepujacy problem: mam metode w singleton beanie ktory jest oznaczona transaction not_supported. ta metoda pobiera liste encji z bazy danych i wrzuca je na liste. nastepnie iterujac po tej liscie kazdy element jest edutowany i zapisywany do bazy, a rownoczesnie wysylany na kolejke. z kolejki odbiera ten obiekt inny system i go oddaje. po oddaniu moj system(operacja w singletonie wciaz trwa) zupelnie inna metoda odbiera dane z kolejki, pobiera obiekt z bazy(ta sama tabela co w singletonie) i elegancko go edytuje. i teraz zagadka ktorej nie rozumiem: poza pisie po odebraniu z kolejki w bazie widze stan jaki chcialbym zobaczyc, jednak kiedy singleton skonczy iterowac po petli to wychodzac z metody obiekty zapisuja sie przez zabrudzenie ze stanem przed trafieniem na kolejke.. jak to mozliwe? przeciez tam nie ma transakcji?

0

Transakcje to są zawsze, wbij to sobie do głowy. Bazy danych sie na nich opierają i KAŻDA operacja w bazie danych jest objęta transakcją. To że ty sobie ręcznie transakcją z poziomu javy nie zarządzasz znaczy tyle że SZBD sam o to zadba i pewnie będzie transakcja per operacja albo coś w tym stylu.

0

no wlasnie chyba nie do konca.. tutaj dziala jakis magiczny mechanizm/architektura EJB. mamy blizniaczy mechanizm w springu.. ten sam kod praktycznie ale kontenerem jest spring i taka sytuacja nie ma miejsca. zreszta gdyby tak bylo to by oznaczalo ze w sytuacji kiedy wykonuje sie dlugotrwala operacja ale juz na samym poczaku przestaje korzystac z obiektu to i tak do czasu zakonczenia calej dlugotrwalej metody nikt inny obiektu nie moze wyedytowac.. a tak nie jest

0

Bzdury i mity. To że ty nie znasz innej metody synchronizacji niż blokowanie rekordów to nie znaczy że twórcy SZBD ich nie znają. Zaręczam ci że nic blokować nie trzeba. A ja bym się właśnie takiego efektu spodziewał jak ten który opisałeś, bo tak by wynikało z uszeregowania transakcji.

0

okej a moze jakas rada jak to zalatwic?

0

Pierwsze co przychodzi do głowy to zadbanie o to żeby nie edytować jednocześnie z dwóch miejsc tych samych rekordów, bo to się dobrze nie skończy.

0

no i to jest racja ale sie nie da tego wyeliminowac. a uproscmy troche te sytuacje: mam metode nietrasakcyjna(not_supported) pobralem liste encji z bazy i sobie zmieniam wlasciwosci tego obiektu. nie robie fizycznie edycji na bazie.. a moja metoda po zakonczeniu wciaz wysyla te obiekty do bazy.. sama:/ dlaczego?

0

A jesteś pewny że dzieje się tak jak napisałeś? Bo ja mam jednak wątpliwości. Sytuacja z twojego pierwszego posta wyląda inaczej: wygląda jakbyś miał jeszcze jakąś transakcje "wyżej" i to ona jest przyczyną twoich problemów.
BTW nie pojmuje czemu kombinujesz z wyłączeniem transakcji w sytuacji kiedy piszesz do bazy (!) i czytasz licząc na spójne dane...

0

odpowiedz jest bardzo prosta.. to jest task ktory wykonuje sie cyklicznie(anotacja schedule w EJB). i teraz jesli na ktorym elemencie z listy poleci mi wyjatek to ja chce to zalogowac a nie cofac cala transakcje czyli kazda iteracja w petli po elementach ma sie wykonac niezaleznie. czy jestem pewien ...tak. chyba ze ejb zaklada jakas transakcje magiczna o ktorej nie wiem - to mozliwe, ale nawet jesli to z opisu not_supported wynika ze moja metoda powinna miec to w nosie

0

Nie bardzo rozumiem co ma tutaj wyjątek i logowanie błędu do cofania transakcji. Przecież możesz wyjątek złapać i zalogować i tyle. Transakcja się wycofa dopiero gdybyś wyskoczył z metody tego EJB za pomocą wyjątku.

0

no chyba niekoniecznie.. jesli poleci np z innego serwisu ten wyjatek to cala tranzakcja zostanie oznaczona jako rollback i juz jest koniec. ale to nie jest meritum sprawy.. chcialbym poznac powod czemu w mojej architekturze dzieje sie to co opisalem a ten sam kod w springu dziala inaczej.

0

Albo co w springu działa inaczej? Przecież Spring nie implementuje EJB. Za pomocą czego dokonujesz w tym springu operacji na bazie danych?

0

za pomoca dokladnie tego samego co w ejb czyli hibernate. dlatego zakladam ze roznica wynika w saym dzialaniu kontenera (spring vs ejb) a nie w sposobie obslugi bazy. moze chodzi o jakas transakcje ejb niezwiazana z sama baza tylko np nie wiem.. z obiektami w pamieci? no generalnie koncza mi sie pomysly.. pewnie czegos nie wiem i jest to prostte do wyjasnienia.. nie daje mi to spokoju

0

Aaaa no paaanie to pisz po ludzku co robisz w tym kodzie. Szklana kula mi się zabrudziła...
Sprawa jest prosta: jeśli jest aktywna sesja hibernate to następuje automatyczne commitowanie zmian w obiektach. Więc jeśli pobrałeś sobie Session i masz je cały czas otwarte i dokonujesz zmian w obiektach encyjnych które za pomocą tego Session wyciągałeś to te obiekty będą automatycznie miały robione saveOrUpdate() nawet jeśli sam go nie wywołasz.

0

no ale wciaz sie pojawia zapytanie.. czemy to dziala inaczej w ejb i w spring. no i teraz.. moze da sie je jakos odpiac w ejb od tej sesji? w sumie jak tak sobie mysle to musze jutro sprawdzic czy przypadkiem nie zamykamy jawnie sesji w aplikacji ze springiem.. bo mozliwe ze tak jest i to by wyjasnialo sprawe. a jak to zrobic w ejb? dodam ze w ejb korzystamy raczej z czystego jpa a jako implementacji uzywamy wlasnie hibernate. nie uzywamy sesji z hibernate tylko entity managera z jpa. masz moze jakis pomysl?

0

Kwestia czy to JPA czy goły Hibernate nie gra tu wielkiej roli. Ot otwarty EntityManager = otwarte Session.
A jak wyglądaja transakcje u ciebie w tym Springu? Bo tam przecież nie możesz nie mieć otwartej transakcji bo sie posypie. Zgaduje że masz tam transakcje na odczyt danych a potem ją kończysz (i tym samym zamykasz sesje). W EJB za to nie masz transakcji na tej metodzie EJB, ale znów skoro ciągniesz dane z JPA to tam musi być jakaś transakcja, więc zgaduje że twoja metoda EJB robi to co powinna, czyli "zawiesza" tą transakcję i wykonuje operacje poza transakcją, ale sesja jest otwarta więc po odwieszeniu merguje sobie zmiany.

0

no i pewnie wlasnie tak jest.. bo operacje w metodzie od razu widac na bazie.. ale po wyjsciu z niej tak jak mowisz emerguje zmiany.. no i w 99% przypadkow nie ma z tym problemu bo i tak jawnie zapisalem zmiany ale w tym konkretnym przypadku nie moge do tego dopuscic.. wiec pytanie brzmi.. jak jawnie w tym ejb mam zamknac sesje na entity managerze?

0

Ja bym zrobił detach() na tych obiektach ;)

0

czyli po edycji na kazdym po prostu detach i bedzie ok? jutro to przetestuje i dam znac;)

0

Jak zrobisz detach() to entitymanager nie powinien tych zmian mergować.
Ale ja nadal trochę nie ogarniam tej twojej logiki którą tu stosujesz. Bo po co w ogóle ten singleton modyfikuje obiekty skoro potem chcesz te modyfikacje olać i zachować te modyfikacje z kolejki?

0

okej to szybkie wprowadzenie.. mamy 3 stany obiektu: waiting , in_progress, done. singleton wciage waitingi i ustawia je na in_progress i pcha na kolejke. inny system wciaga z kolejki i jesli poprawnio obsluzyl to mi odsyla i mowi ze skonczyl wiec powinienem ustawic done. no i problem byl taki ze nawet jesli ustawilem done to moj singleton(@schedule) przez zabrudzenie zapisywal z powrotem in_progress. no i cala filozofia:)

0

Ale ja w takim razie nie rozumiem w ogóle tych cudów na kiju z jakimiś transakcjami lewymi. Singleton pobiera sobie listę, robi ładny update za pomocą hqla / jpqla jednym zapytaniem, commituje te zmiany i wrzuca w kolejke (bo rozumiem że updatowałeś to rekord po rekordzie i było za wolno i dlatego chciałeś od razu po jednym obiekcie wrzucać do kolejki?). Scheduler wyciąga z kolejki i sie bawi. W czym problem?
Albo lepiej: po co w ogóle ten singleton? Czemu scheduler sam po wyciągnięciu obiektu nie ustawia mu in_progress a potem nie zmienia na done?

0

scheduler wrzuca na kolejke ustawiajac na inprogress i leci dalej z kolejnymi obiektami.. kolejka dziala niezaleznie i zmienia sobie obiekt w bazie na done. poniewaz scheduler dziala dluzej niz pojedyncza operacja zmiany na done.. to po wyjsciu nadpisuje zmiany swoim inprogress.. prosciej nie umiem wyjasnic:P moze daloby sie to zrobic prosciej ale takiego rozwiazania wymagala architektura wszystkich naszych systemow a to juz zupelnie inny temat.. wk azdym razie jhestem praktycznie przekonany ze odpiecie obiektu z otwartej sesji zalatwi sprawe. jutro dam znac:)

0

ok wyglada na to ze detach zadzialal. dzieki za pomoc. ale jest cieka2wostka: detach musi byc wywolany dokladnie w tym samym serwisie w ktory zostal zrobiony find. czesc operacji delegujemy do innego serwisu i tam odpiecie nie zadzialalo!

0

A czemu miałoby niby zadziałać? W tym innym serwisie za pewne te obiekty nie są już podpięte po prostu ;] Przecież jak je zserializujesz i z deserializujesz, albo wyjdziesz poza ramy transakcji / sesji to odpięcie jest automatyczne.
Nawet gdybyś tych obiektów nie odpiął, to zapewne żadna ze zmian wprowadzonych w tym drugiej serwisie nie zostałaby "automatycznie mergowana".

0

no pewnie masz racje:) w kazdym raize wiekszy temat:) ja zawsze utozsamialem transakcje z se4sja a jednak okazuje sie ze to bylo duzym bledem:)

0

Ehhh a ze zwykłym SQL nie byłoby takich problemów :)

0

to akurat swieta racja:P ale co zrobisz.. kazda technologia niesie swoje zasaday, z ktorymi nie warto walczyc. te akurat maja swoj zawily sens:)

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