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

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)

3

zainteresuj się tematem multitenancy, tu masz przykład tutoriala
https://medium.com/swlh/multi[...]g-boot-hibernate-6a8e3ecb251a

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.

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.

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]
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ś.

1

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

1

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.

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