webForumDet fria alternativet

Arkitektur för att slippa öppna och stänga databas flera gånger

.NET

34 svar · 1 571 visningar · startad av Pace · sida 2 av 2

Frågan, av Pace

Jag har en applikation som tillåter moduler från tredje part. Dock används samma datakälla vilket i nuläget innebär att huvudapplikationen öppnar och stänger databasen, för att sedan låta modulerna göra likadant. Om vi säger att varje modul (plus huvudapplikationen) gör likadant minst en gång, blir antalet anslutningar i direkt proportion till antalet moduler. Det är inte bra. (En connection pool

Läs frågan i sin helhet →
Medlem sedan aug. 20003 575 inlägg
#21

erka skrev:

Förstår inte hur du menar med ASP.NET och att det är skillnad där, connectionpool ligger per connectionstring, så det är inget specifikt för asp.net utan ado.net, om du inte har byggt din lösning så olika installationer har olika anslutningar. Och oavsett vad så blir det bra mycket bättre prestanda med pooling eller inte, det är ju framtaget för förhindra resursslukande vid skapande av anslutningar. Trots du har en gemensam pool på en asp.net så har du ju även en pool på din enskilda app. Lösningen kanske är att ta ett SOA-approach till dina tjänster för att dela. Men jag är faktiskt inte heler säker på att inte ADO.NET snackar med MSSQL och låter den sköta connectionpoolingen, men jag tror det är ramverket som hanterar det själv :)

Minnet kanske blir det samma om den ligger i poolen, men det tar prestanda från sql-servern att skapa ett "connectionobjekt", det är det som tar kräm. Det a området p.g.a. hur man skall bygga sin arkitektur med NHibernate eftersom tar inte alls lika mycket prestanda att återanvända ett från poolen.

Absolut du har rätt, det tar tid att skapa en koppling men det är inte riktigt det svaret jag är ute efter.

Det jag menade var att man har en connected architecture dvs man använder samma koppling i hela programmet. Som hela tiden är öppen.

Jag är lite nyfiken på detta för jag är rejält insnöad på NHibernate och tycker det är grymt bra.

Men just denna frågan är ganska viktig hur en sql server kan hantera det kopplingar osv.

Medlem sedan dec. 19996 522 inlägg
#22

Fast har du inte missuppfattat nhibernates hantering av hibernate sessionen, det vanligaste är ju att man använder sig av session-per-request och den håller ju inte en connectionobjekt öppen hela tiden. Använder man sig av andra pattern för sessionen är de ju rätt tydliga med att det jag har hittat ang. connected architecture är anti-patterns

1.A first naive implementation might keep the Session and database transaction open during user think time, with locks held in the database to prevent concurrent modification, and to guarantee isolation and atomicity. This is of course an anti-pattern, since lock contention would not allow the application to scale with the number of concurrent users.

2. A Session will not obtain a JDBC Connection (or a Datasource) unless it is needed, hence consume no resources until used.

Eller är du ute efter att ha en session som aldrig stängs i hela applikationen, den stängs ju efter commit med automatik om man kör det normala sessionsmönstret. Vill du kunna använda lazy-load fullt ut och utan konstigheter fast slippa ha en konstant öppen anslutning kanske mönstret session in view kan vara något

Har jag missuppfattat vad det är du undrar

Medlem sedan aug. 20003 575 inlägg
#23

erka skrev:

Fast har du inte missuppfattat nhibernates hantering av hibernate sessionen, det vanligaste är ju att man använder sig av session-per-request och den håller ju inte en connectionobjekt öppen hela tiden. Använder man sig av andra pattern för sessionen är de ju rätt tydliga med att det jag har hittat ang. connected architecture är anti-patterns

Eller är du ute efter att ha en session som aldrig stängs i hela applikationen, den stängs ju efter commit med automatik om man kör det normala sessionsmönstret

Har jag missuppfattat vad det är du undrar

Jo man kan använda det så, men om man vill använda vilket jag tycker är en stor fördel Lazyloading så måste man nog ha den igång om det nu inte finns någon inställning för det men jag har inte sett någon.

Jag förutsätter att den texten du fått tag på är javaversionen då det pratas om
jdbc där jag är osäker på om det finns någon liknande connection pooling?

Medlem sedan dec. 19996 522 inlägg
#24

Red. ovan, Vill du kunna använda lazy-load fullt ut och utan konstigheter fast slippa ha en konstant öppen anslutning kanske mönstret session in view kan vara något. Tror Benjamin Day har skrivit om det

Medlem sedan maj 20012 812 inlägg
#25

Nickemannen skrev:

Jo man kan använda det så, men om man vill använda vilket jag tycker är en stor fördel Lazyloading så måste man nog ha den igång om det nu inte finns någon inställning för det men jag har inte sett någon.

Jag har som sagt inte använd NHibernate, men varför tror du att du måste ha en öppen koppling till din databas för att du skall kunna använda dig av lazyloading?

Som jag ser det så behöver den inte alls vara öppen, eftersom det knappast är databasen som bestämer när och hur du skall ladda din data, utan NHibernate tillsammans med din kod.

- M

Medlem sedan maj 20012 812 inlägg
#26

nickemannen skrev:

Exakt, när det inte gäller en asp.net koppling så borde poolen bara innehålla en koppling om inte flera program kör mot samma databas. Då skulle det ju kunna hända att den har fler om den får oturen att det utförs saker på kopplingen samitidigt.

Nja, om du använder en connectionpool så skapas det alltid upp ett visst antal minimum kopplingar som ligger där redo, så även om du i din vanliga applikation använder dig av connectionpoolen så kommer där ligga typ 5 öppna kopplingar som du kan använda dig av. Dessutom så läste jag någonstans att du har inte en connectionpool per klient, ut typ 1 connectionpool per applikation/appdomain som använder sig av ADO.NET och dessutom tror jag till och med det var 1 connectionpool per connectionstring. Så om du i din applikation kallar på 2 olika databaser på samma SQL Server, så kommer du ha 2 olika connectionpools som båda har typ 5 öppna kopplingar.

Det är just det som gör det svårt för mig att tro att varje koppling i en connectionpool motsvaras av en öppen koppling på servern, jag tror mer att servern också har en connectionpool som de öppna kopplingarna på klienterna använder sig av. Så helt enkelt så finns det en koppling mellan en öppen koppling i connectionpoolen och en öppning på servern, vilket gör att för varje koppling i connectionpoolen så finns det INTE en öppen koppling på servern.

Medans om du gör en connection.open() så öppnar man kopplingen hela vägen från klienten till servern och snor resurser på servern.

Jag har dock ställt frågan vidare till en SQL Server Guru som jag hittade på nätet, och personen skulle ta sig en funderar innan han svarade.

- M

Medlem sedan dec. 19996 522 inlägg
#27

Gladh har rätt ang. poolerna. Nikemannen, slå på en trace på sql-servern, se hur den använder sp_reset_connection, för poolhanteringen

Medlem sedan aug. 20003 575 inlägg
#28

Gladh skrev:

Nickemannen skrev:

Jo man kan använda det så, men om man vill använda vilket jag tycker är en stor fördel Lazyloading så måste man nog ha den igång om det nu inte finns någon inställning för det men jag har inte sett någon.

Jag har som sagt inte använd NHibernate, men varför tror du att du måste ha en öppen koppling till din databas för att du skall kunna använda dig av lazyloading?

Som jag ser det så behöver den inte alls vara öppen, eftersom det knappast är databasen som bestämer när och hur du skall ladda din data, utan NHibernate tillsammans med din kod.

- M

Japp satt och tänkte på detta igår, och jag har antagligen lurat mig i mig själv att

ISession.Disconnect() betyder att databaskopplingen stängs och att ISession.Resume() betyder att databaskopplingen öppnas.

Men så behöver det ju inte alls vara utan när man tar disconnet så kanske det betyder att man inte ska kunna ansluta igen. Ska kolla upp detta.

Men frågan om det där med connectionpool och att hålla en connection öppen hela tiden är högst intressant, även om jag kan hålla med om att i de flesta fall så lönar det sig att man stänger den och låter .net ta hand om hanteringen.

Medlem sedan aug. 20003 575 inlägg
#29

Gladh skrev:

nickemannen skrev:

Exakt, när det inte gäller en asp.net koppling så borde poolen bara innehålla en koppling om inte flera program kör mot samma databas. Då skulle det ju kunna hända att den har fler om den får oturen att det utförs saker på kopplingen samitidigt.

Nja, om du använder en connectionpool så skapas det alltid upp ett visst antal minimum kopplingar som ligger där redo, så även om du i din vanliga applikation använder dig av connectionpoolen så kommer där ligga typ 5 öppna kopplingar som du kan använda dig av. Dessutom så läste jag någonstans att du har inte en connectionpool per klient, ut typ 1 connectionpool per applikation/appdomain som använder sig av ADO.NET och dessutom tror jag till och med det var 1 connectionpool per connectionstring. Så om du i din applikation kallar på 2 olika databaser på samma SQL Server, så kommer du ha 2 olika connectionpools som båda har typ 5 öppna kopplingar.

Det är just det som gör det svårt för mig att tro att varje koppling i en connectionpool motsvaras av en öppen koppling på servern, jag tror mer att servern också har en connectionpool som de öppna kopplingarna på klienterna använder sig av. Så helt enkelt så finns det en koppling mellan en öppen koppling i connectionpoolen och en öppning på servern, vilket gör att för varje koppling i connectionpoolen så finns det INTE en öppen koppling på servern.

Medans om du gör en connection.open() så öppnar man kopplingen hela vägen från klienten till servern och snor resurser på servern.

Jag har dock ställt frågan vidare till en SQL Server Guru som jag hittade på nätet, och personen skulle ta sig en funderar innan han svarade.

- M

Låter toppen väntar på svar då (y)

Medlem sedan dec. 19996 522 inlägg
#30

Jag har som sagt inte använd NHibernate, men varför tror du att du måste ha en öppen koppling till din databas för att du skall kunna använda dig av lazyloading?

Det är en bra fråga, jag använder inte Lazy med hibernate utan kör med Cache och diverse andra lösningar då just en aktuell lösning ligger i en webfarm. Men jag vet att för att Lazy ska fungera kan man inte stänga hibernate-sessionen, hibernate stödjer inte lazy på disconnected objects nämligen. Men man komma förbi det på ett sätt via Active View mönstret.

Medlem sedan aug. 20003 575 inlägg
#31

erka skrev:

Det är en bra fråga, jag använder inte Lazy med hibernate utan kör med Cache och diverse andra lösningar då just en aktuell lösning ligger i en webfarm. Men jag vet att för att Lazy ska fungera kan man inte stänga hibernate-sessionen, hibernate stödjer inte lazy på disconnected objects nämligen. Men man komma förbi det på ett sätt via Active View mönstret.

Det kan nog vara så som jag skrev tidigare att bara för sessionen är connected kanske inte det behöver betyda att databaskopplingen är det.

Medlem sedan maj 20012 812 inlägg
#32

erka skrev:

stänga hibernate-sessionen, hibernate stödjer inte lazy på disconnected objects nämligen.

Det är nog som nickemannen skrev. Jag kan förstå att man kanske måste ha hibernate sessionen öppen, eftersom den garanterat har informationen om när/hur/varför din LazyLoad data skall laddas. Det betyder ju inte att databasen måste vara öppen. Det räcker ju att man öppnar den precis när man skall hämta datan som skall lazyloadas, och sedan stänger kopplingen igen. Eftersom själva databaskopplingen inte har något som helst med själva Lazyloadingen att göra, så finns det ingen som helst anledning att ha kopplingen öppen hela tiden.

Nickemannen skrev:

Låter toppen väntar på svar då

Nja... jag fick tillbaka ett mail med en massa länkar, men jag tyckte inte jag hittade något där som berättade hur SQL Servern hanterar alla kopplingar från de olika klienterna. Skall se om man kan skicka frågan till någon på MS.

Här är iallafall länkarna om någon annan kanske kan hitta det som jag missade.

http://www.sql-server-performance.com/tips/ado_net_performance_p1.aspx
http://msdn2.microsoft.com/en-us/library/Aa964124.aspx
http://msdn2.microsoft.com/en-us/library/ms345135.aspx
http://msdn2.microsoft.com/en-us/library/ms131395.aspx
http://msdn2.microsoft.com/en-us/library/ms131686.aspx

- M

Medlem sedan dec. 19996 522 inlägg
#33

Nej det verkar befängt, som jag skrev tidigare, tror inte heller det fungerar så, bara å slå på din sql profiler å kolla

Medlem sedan aug. 20003 575 inlägg
#34

Vad jag har läst lite när jag sökt idag så fungerar poolerna lite annorlunda beroende på vad det är för databas.

Så det kan nog finnas någon speciell hantering mellan .net klienten och sql servern, iallfall från version 7+ av ms sql server :).
Jaja men då börjar vi ju komma fram till ett bra slutsats :).

Medlem sedan maj 20012 812 inlägg
#35

Jag har nu fått svar på min fråga angåend serverns hantering av connectionpoolen. Och det verkar som servern har sin egen connectionpool för inkommande connections.

The connection pool behaves much like a client side memory pool. As you say, the goal is to minimize the number of actual disconnect / connect requests in clients that connect / disconnect frequently because the connect overhead is significant. The pool behaves in a similar manner to a memory pool in that it only allocates new connections if old connections are all in use or die due to timeout. In this way, it does not connect 5 times the first time a client tries to connect, it connects 1 time, and on disconnect leaves it open. The driver manager pools connections based on attributes that cannot be changed once the client is in a connected state (e.g. user / password/server ) and "fixes up" the rest of the attributes on connect. So you may have an application that connects / disconnects quite frequently to different databases on the same server under the same user and its behavior under a connection pool is simply to connect one time and change databases frequently. Sometimes connections will die based on a preset disuse timeout, and new ones will need to be allocated, but the general behavior is identical to what one would expect of a user level memory pool with a user defined max pool size. New connections are only allocated when needed, and any components of a connection at the client level that can be changed after connect are modified on subsequent connect calls after retrieving a valid connection with the same immutable characteristics.

Så även om man skriver databasfrågor för vanliga klientapplikationern så är connectionpoolen den bästa lösningen..

- M

273 ms totalt · 4 externa anrop · v20260731065814-full.6fe65c25
127 ms — deklarationer (db)
0 ms — hämta statistik (cache)
143 ms — hämta tråd, inlägg och bilagor (db)
124 ms — ändringar (db)