Oddzielne schematy/bazy danych per kraj

Odpowiedz Nowy wątek
2018-11-17 22:48
0

Do tej pory programowałem w PHP i tam sprawa była prosta, ponieważ cała aplikacja ma request scope. Co request tworzy się nowe połączenie do bazy danych, więc wystarczyło za każdym razem wczytać odpowiedni config na podstawie domeny i voilà - mamy połączenie z odpowiednią bazą.

Z tego co wiem, to PHP jest pod tym względem wyjątkiem. W C#, Javie i innych aplikacja cały czas działa. Mamy za to do dyspozycji request scope, session scope i inne, jeżeli chodzi o serwisy. W jaki sposób byście to zrobili? Technologie jak w tagach.

edytowany 2x, ostatnio: Desu, 2018-11-17 22:48

Pozostało 580 znaków

2018-11-17 22:54
2

Z tego co wiem, to PHP jest pod tym względem wyjątkiem. W C#, Javie i innych aplikacja cały czas działa.

Masz rację w takim języku jak C# aplikacje działają, nie to co w PHP. W C# też masz request scope i możesz nawiązać connection z bazą per request. Najłatwiej to ogarnąć jakimś kontenerem DI.

"Masz rację w takim języku jak C# aplikacje działają, nie to co w PHP. " - Good one :D - Desu 2018-11-17 22:54

Pozostało 580 znaków

2018-11-17 22:57
0

No właśnie, ciekawy byłem, czy zrobienie tego przez request scope jest prawidłowym rozwiązaniem. Wiadomo, zawsze można coś wykombinować, ale ponieważ nie mam jeszcze za dużej wiedzy na ten temat, to chciałem potwierdzić swoje przypuszczenia. Zwłaszcza, że inni programiści, z którymi rozmawiałem na ten temat mówili, że jest to trudne/niewykonalne.

edytowany 2x, ostatnio: Desu, 2018-11-17 22:58

Pozostało 580 znaków

2018-11-17 23:05
1

Takie rozwiązanie moim zdaniem będzie ok.
EDIT: Ale co jest nie wykonalne?

edytowany 1x, ostatnio: error91, 2018-11-17 23:06

Pozostało 580 znaków

2018-11-18 00:30
0

Podobno nie mogli tego zrobić i padło takie słowo, ale u mnie działa ;)

Pozostało 580 znaków

2018-11-18 10:29
2

Nie bardzo wiem o czym wy tutaj rozmawiacie, chcecie mieć otwarte połączenie do bazy przez cały czas trwania requesta ? Po co?
Powszechnym zaleceniem jest trzymanie otwartego połączenia jak najkrócej się tylko da, bo liczba możliwych jednoczesnych połączeń jest ograniczona. Połączenia są brane z puli, więc otwieranie i zamykanie połączeń jest znacznie lepszym pomysłem niż trzymanie otwartego połączenia przez cały request.


#Dżunior React Devloper wanna be#

Pozostało 580 znaków

2018-11-18 12:19
0

Nie, zupełnie nie o to mi chodziło. Zgadzam się z Twoim stwierdzeniem. Miałem na myśli połączenie z konkretną baza lub odwolanie do konkretnego schematu bazując lokalizacyjnych z requestu.

edytowany 1x, ostatnio: error91, 2018-11-18 12:20

Pozostało 580 znaków

2018-11-18 12:28
0

@neves: to czemu domyślnie EF ma ustawiony DbContext na scoped? Może mieszam pojęcia i DbContext to coś innego niż połączenie. Póki co chodzę troche jak dziecko we mgle.

Chodziło o to, żeby używać różnych baz w zależności od języka (wyciąganego z HttpContext). Gość z którym rozmawiałem zna .net'a dłużej niż ja (ja znam go całe dwa tygodnie..) i miał problem ze skonfigurowaniem tego. Do tej pory robiłem w PHP, a tam rzeczy są robione na różne dziwne sposoby i chciałem się upewnić, że to rozwiązanie, które znalazłem jest okej, a wygląda to tak:

 var connectionString = _config.GetConnectionString("EntityContext");

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddScoped(p => p.GetService<IHttpContextAccessor>()?.HttpContext);

services.AddEntityFrameworkNpgsql()
    .AddDbContext<EntityContext>(
        (serviceProvider, options) => {
            var httpContext = serviceProvider.GetService<HttpContext>();
            // here we can get language from header or whatever
            var locale = httpContext.Request.Query["locale"].ToString();

            options
                .UseLazyLoadingProxies()
                .UseNpgsql(String.Format(connectionString, locale));
        });
edytowany 5x, ostatnio: Desu, 2018-11-18 12:37

Pozostało 580 znaków

2018-11-18 13:31

DbContext to nie to samo co połączenie, DbContext to UnitOfWork które samo zarządza otwieraniem i zamykaniem połączeń wtedy kiedy potrzebuje i nie prześlemy mu jakiegoś explicite.

Jak mamy db context per request, to może się zdarzyć że w dwóch miejscach będziemy mieć wstrzykniętą tą samą instancję dbcontexta, to pierwsze miejsce może porobić na nim różne rzeczy bez zapisywania zmian, a to drugie miejsce być tego nieświadome i dostać zabrudzony dbcontext, dlatego jest bezpieczniej jednak ustawiać dbcontext jako Transient.

Inaczej też ujmując jak mamy dbcontext per request, to nigdy nie mamy pewności że dostajemy czysty dbcontext bez żadnych wprowadzanych i nie zapisanych zmian z innego fragmentu kodu, które możemy nieświadomie teraz zapisać , nie sprzyja to zdecydowanie izolacji i przejrzystości.

A kod wygląda jak najbardziej poprawnie ;)


#Dżunior React Devloper wanna be#
edytowany 2x, ostatnio: neves, 2018-11-18 13:36

Pozostało 580 znaków

2018-11-18 16:25
1
neves napisał(a):

DbContext to nie to samo co połączenie, DbContext to UnitOfWork które samo zarządza otwieraniem i zamykaniem połączeń wtedy kiedy potrzebuje i nie prześlemy mu jakiegoś explicite.

Jak mamy db context per request, to może się zdarzyć że w dwóch miejscach będziemy mieć wstrzykniętą tą samą instancję dbcontexta, to pierwsze miejsce może porobić na nim różne rzeczy bez zapisywania zmian, a to drugie miejsce być tego nieświadome i dostać zabrudzony dbcontext, dlatego jest bezpieczniej jednak ustawiać dbcontext jako Transient.

Inaczej też ujmując jak mamy dbcontext per request, to nigdy nie mamy pewności że dostajemy czysty dbcontext bez żadnych wprowadzanych i nie zapisanych zmian z innego fragmentu kodu, które możemy nieświadomie teraz zapisać , nie sprzyja to zdecydowanie izolacji i przejrzystości.

A kod wygląda jak najbardziej poprawnie ;)

Hmm.. argument że ktoś coś zmienił u nie zapisał do mnie nie trafia i brzmi jak jakiś code smell, chyba że miałeś coś innego na myśli. Przy rejestracji transient I używaniu contextu w dwóch różnych miejscach tracisz właśnie korzyści Unit of work ponieważ gdy zmienisz coś w jednym serwisie a nastepnie w drugim serwisie wstrzykniesz nowy dbcontext to gdy coś pójdzie nie tak to nie jesteś w stanie w prosty sposób wycofać pierwszej operacji bo tam uzywales już innego contextu. W większości przypadków porządane jest aby przy jednym żądaniu http wykonały się wszystkie operacje a nie połowa. Drugą sprawą mniej ważna szczególnie jeśli chodzi o EF jest cache który jest czyszczony przy każdym nowym dbcontexcie.

Pozostało 580 znaków

2018-11-18 18:10
0
error91 napisał(a):

Hmm.. argument że ktoś coś zmienił u nie zapisał do mnie nie trafia i brzmi jak jakiś code smell, chyba że miałeś coś innego na myśli. Przy rejestracji transient I używaniu contextu w dwóch różnych miejscach tracisz właśnie korzyści Unit of work ponieważ gdy zmienisz coś w jednym serwisie a nastepnie w drugim serwisie wstrzykniesz nowy dbcontext to gdy coś pójdzie nie tak to nie jesteś w stanie w prosty sposób wycofać pierwszej operacji bo tam uzywales już innego contextu. W większości przypadków porządane jest aby przy jednym żądaniu http wykonały się wszystkie operacje a nie połowa. Drugą sprawą mniej ważna szczególnie jeśli chodzi o EF jest cache który jest czyszczony przy każdym nowym dbcontexcie.

Masz dwa serwisy S1, S2 do których wstrzykujesz bezpośrednio ten sam dbContext, i chcesz mieć je w jednej biznesowej transakcji. Gdzie wywołujesz saveChanges :)?
A co jeśli kolejność wywołania serwisów się zmieni?
A co jak dodamy kolejny serwis wywoływany przed nimi S3 który nie wchodzi w skład powyższej biznesowej transakcji, SaveChanges rzuci błędem, a nasze serwisy S1 S2 dostaną ten sam datacontext :)?


#Dżunior React Devloper wanna be#

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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