Wpis z mikrobloga

Robię findBySth(SELECT) potem ifPresent, jeśli false to tworzenie nowego obiektu i save(INSERT).
Teraz jest samo @Transactional.
Bazy danych do testów MariaDB z domyślnym silnikiem, PostgresSQL.
Jeśli wyśle z unit testu drugie zapytanie w czasie wykonywania pierwszego to w bazie w tabeli są już 2 wiersze.
W PostgreSQL domyślnym poziomem izolacji jest Read committed.

Tam gdzie nie trzeba nic zwracać to można dać do kolejki i tyle.
Są jednak przypadki, że endpoint musi zwracać odpowiedź z pewnymi danymi od razu.
Co będzie dostatecznym rozwiązaniem?
1. Przetestować wszystkie endpointy i te gdzie występuje ten problem zrobić lock na wierszach (SELECT FOR UPDATE).
2. Przechowywać stan w pamięci aplikacji i co pewnien czas synchronizować z bazą.
3. Trigger po insercie z RAISE EXCEPTION.
4. Napisać @Transactional Serializable nad endpointami
#spring #java #springboot #bazydanych
  • 2
@100x:
Czyli szukasz czegoś na bazie, jak tego nie znajdziesz to tworzysz to i zwracasz użytkownikowi, tak?
Twój problem polega na tym, że jeżeli w tym samym czasie, dwie osoby wywołają szukanie, to duplikuje Ci rekordy w bazie danych?
Jeśli dobrze rozumiem, to możesz chyba ustawić unikalność na bazie. Wtedy drugi insert się wywali i nie będziesz miał duplikatów.
via Wykop Mobilny (Android)
  • 0
@100x:
Najłatwiej mieć unikatową kolumnę jak @kenshin985 napisał. Od biedy w niektórych zastosowaniach nada się też kolumna z hashem kilku pól modelu.
Jeśli masz jakąś zależność od innych rekordów, to IMO lock będzie drugą najlepszą opcją. Typu relacja AUTO do wielu CZESCI. Zalockowanie auta spowolni tylko równoległe operacje na tym aucie, a nie niepotrzebnie wszystkie na tym endpoincie.

Opcja 2 to już prawie inwalidacja cache i tylko czekać na bugi i