Spring Boot polaczenie do różnych baz na podstawie nazwy użytkownika

Spring Boot polaczenie do różnych baz na podstawie nazwy użytkownika
Jarek Korcek
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 29
0

Aplikacja jest napisana w Spring Boot'cie. Każdy użytkownik ma utworzoną swoją bazę danych (każda baza ma taki sam schemat).
Nazwę bazy użytkownika mam zapisaną w głównej bazie serwisu, wiec na podstawie nazwy użytkownika wiem na jakiej bazie powinienem operować.
Pytanie w jaki sposób na poziomie RESTa łączyć się z konkretną bazą użytkownika i wykonywać na niej zapytania? (Zmiana połączenia nie może być globalna, bo wtedy odpytanie RESTa przez innych mogłoby się odbyć przypadkowo na nieprawidłowej bazie)

IH
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 103
3

zainteresuj się tematem multitenancy, tu masz przykład tutoriala
https://medium.com/swlh/multi-tenancy-implementation-using-spring-boot-hibernate-6a8e3ecb251a

damianem
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 205
2

Tworzysz sobie coś w stylu DataSourceProvider z metodą DataSource getDataSource(String userName) która w sposób lazy tworzy i zwraca kolejne obiekty DataSource (z opcją cache w zwłykłej mapie). Tak wyciągnięte DataSource dla tego usera opakowywujesz w dowolną abstrakcję do dostępu do bazy której używasz (pewnie ORM) i normalnie używasz.

Podejrzewam że chciałbyś żeby wszystkie magie Springowe typu repozytoria ze spring-data działały - do tego potrzebujesz singleton DataSource w kontekście aplikacji - można zrobić prostą implementację tego interfejsu, która może mieć wstrzyknięty request scoped bean zwracający nazwę usera wykonującego bieżący request i z pomocą tego beana będzie delegowała już do konkretnego DataSource.

Jarek Korcek
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 29
0

@IHaveHandedInMyResignation: Skorzystałem z tego artykułu, ale pojawił się problem z niezamykanymi połączeniami po zakończeniu restowego requesta. Close na DataSource.getConnection().close() nic nie daje.

Kopiuj
org.postgresql.util.PSQLException: KATASTROFALNY: przepraszamy, mamy już zbyt wiele klientów (pgjdbc: autodetected server-encoding to be ISO-8859-2, if the message is not readable, please check database logs and/or host, port, dbname, user, password, pg_hba.conf)
	at org.postgresql.core.v3.ConnectionFactoryImpl.doAuthentication(ConnectionFactoryImpl.java:613) ~[postgresql-42.2.16.jar:42.2.16]
	at org.postgresql.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:161) ~[postgresql-42.2.16.jar:42.2.16]
	at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:213) ~[postgresql-42.2.16.jar:42.2.16]
	at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:51) ~[postgresql-42.2.16.jar:42.2.16]
IH
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 103
0

Musiałbyś sprawdzić ile masz połączeń do bazy danych. Prawdopodobnie nie zamykasz gdzieś połączenia i masz, na przykład limit 20połączeń, które wykorzystałeś.

Shalom
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Space: the final frontier
  • Postów: 26433
1

Nie rób tych połączeń ręcznie tylko za pomocą jakiegoś Hikari pool, to samo będzie ogarniać połączenia.

superdurszlak
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Kraków
  • Postów: 2003
2

Możliwe, że to czego szukasz to Springowy AbstractRoutingDataSource

Pod spodem może leżeć wiele data sourców, mogą być np. podpięte do tych baz użytkowników. Konkretny data source jesteś w stanie wybrać na podstawie kontekstu żądania - nie ma potrzeby ustawiania niczego globalnie. Możesz mieć osobny datasource wskazujący na bazę / schemat należący do danego tenanta, jesteś w stanie zidentyfikować je po kluczu i każdorazowo wybierać datasource spięty z bazą tenanta, który wywołał żądanie.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.