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)
Spring Boot polaczenie do różnych baz na podstawie nazwy użytkownika
- Rejestracja: dni
- Ostatnio: dni
- Postów: 29
- Rejestracja: dni
- Ostatnio: dni
- Postów: 103
zainteresuj się tematem multitenancy, tu masz przykład tutoriala
https://medium.com/swlh/multi-tenancy-implementation-using-spring-boot-hibernate-6a8e3ecb251a
- Rejestracja: dni
- Ostatnio: dni
- Postów: 205
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.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 29
@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]
- Rejestracja: dni
- Ostatnio: dni
- Postów: 103
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ś.
- Rejestracja: dni
- Ostatnio: dni
- Lokalizacja: Space: the final frontier
- Postów: 26433
Nie rób tych połączeń ręcznie tylko za pomocą jakiegoś Hikari pool, to samo będzie ogarniać połączenia.
- Rejestracja: dni
- Ostatnio: dni
- Lokalizacja: Kraków
- Postów: 2003
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.