Pro upřesnění – Node.js není jednovláknové. Kód vaší aplikace se spouští v jednom vláknu, ale pod kapotou je používá, když je potřeba – podívejte se zde (odpověď i komentáře pod ní):
A:
Jak můžete vidět mysql
modul, který používáte, vyžaduje, abyste předali zpětné volání pro query()
metoda (a pravděpodobně pro mnoho dalších). Takže když to zavoláte, provádění vašeho kódu pokračuje a zpětné volání je voláno, když dorazí výsledky z databáze.
K vaší otázce - nevytváříte nové připojení pro každý požadavek. Podívejte se na readme soubor mysql
modul, Pooling Connections sekce
:
Když zavoláte dbPool.getConnection()
připojení se vytvoří pouze v případě, že ve fondu již nejsou žádná dostupná připojení – v opačném případě pouze chytne jedno z horní části. Volání objConn.release()
uvolní připojení zpět k fondu – neodpojuje se. Toto volání umožňuje jeho opětovné použití jinými částmi vaší aplikace.
Abych to shrnul:
- Vytvářet nové připojení pro každý požadavek není dobrý nápad protože bude využívat více zdrojů (CPU, RAM) na počítačích vaší aplikace i databáze.
- Používání jednoho připojení pro všechny požadavky je také nesprávné, protože pokud dokončení některé z operací trvá dlouho, vaše připojení se zablokuje a všechny ostatní požadavky na něj čekají.
- Použití fondu připojení je skvělý nápad, který vám umožňuje provádět více operací s vaší databází současně, i když dokončení jedné z nich trvá dlouho.
Aktualizace: Chcete-li odpovědět na otázky z komentářů:
Když používáte jedno připojení pro každý požadavek, mysql
modul musí otevřít nový soket, připojit se k databázi a ověřit před zadáním dotazu - to zabere čas a spotřebuje to nějaké zdroje. Kvůli tomu je to špatný přístup.
Na druhou stranu při použití pouze jednoho připojení (nikoli fond připojení), spuštění dotazu, jehož dokončení trvá dlouho, zablokuje všechny další dotazy na toto připojení, dokud nebude dokončeno – což znamená, že jakýkoli jiný požadavek bude muset počkat. Je to také špatný přístup.
Vytvoření nového fondu připojení pro každý požadavek je skoro jako použití nového připojení, pokud nezavoláte pool.getConnection()
vícekrát – pak je to ještě horší (vezměte zdroje použité vytvořením nového připojení a vynásobte je počtem pool.getConnection()
hovory).
Pro další objasnění jednoho připojení pro každou operaci vs všechny operace v jednom připojení otázka:
Každá operace v každém připojení je spuštěna po dokončení předchozí (je synchronní, ale ne na straně klienta), takže pokud máte tabulku s několika miliardami řádků a problém SELECT * FROM yourtable
dokončení bude nějakou dobu trvat a zablokuje každou operaci na tomto připojení, dokud nebude dokončena.
Pokud máte pro každou operaci jedno připojení, které je třeba vydávat paralelně (např. pro každý požadavek), problém zmizí. Ale jak již bylo uvedeno dříve, otevření nového připojení vyžaduje čas a zdroje, a proto fond připojení byl představen koncept.
Odpověď tedy zní:použijte jeden fond připojení pro všechny požadavky (stejně jako ve svém příkladu kódu) – počet připojení se přizpůsobí provozu ve vaší aplikaci.
Aktualizace č. 2:
Na základě připomínek vidím, že bych měl také vysvětlit koncept poolů připojení. Funguje to tak, že spustíte aplikaci s prázdným fondem připojení a inicializovaným tak, aby vytvořil maximálně n připojení (afaik je to 10 pro mysql
modul ve výchozím nastavení).
Kdykoli zavoláte dbPool.getConnection()
zkontroluje, zda jsou ve fondu nějaká dostupná připojení. Pokud existuje, chytne jeden (učiní jej nedostupným), pokud ne, vytvoří nový. Pokud je dosaženo limitu připojení a nejsou k dispozici žádná připojení, dojde k nějaké výjimce.
Volání connection.release()
uvolní připojení zpět k fondu, aby bylo znovu dostupné.
Použití fondu k získání pouze jednoho globálního připojení pro celou aplikaci je zcela špatné a proti samotnému konceptu (totéž můžete udělat pouhým vytvořením připojení ručně), takže použijte fond připojení Mám na mysli použijte fond připojení tak, jak měl být používán – abyste z něj získali připojení, když je potřebujete .