Why is there more DB connection pool than main thread in Webflux? - spring-webflux

I use Webflux R2DBC.
I know, the default value creates 1 thread per CPU core.
However, I know that the default value of R2DBC's connection pool is 10.
I can't understood that....
DB connections operate asynchronously. Then, DB connection don't need many thread pool.
Because the DB connection only sends and receives, connection can do other work(other sending or receiving) while waiting for it.
Rather, since the main thread(1 per CPU core) performs various calculations, the number of main threads should be large.
What am I missing?

I think you kind of have it backwards.
since the main thread(1 per CPU core) performs various calculations, the number of main threads should be large.
A (logical) CPU can perform only one task at a time and since threads in a reactive application should never just wait, since all calls are non-blocking, it doesn't make sense to have more threads than CPU's.
DB connections operate asynchronously. Then, DB connection don't need many thread pool.
Correct, you don't need a thread pool for your database connectivity. But a connection pool isn't a thread pool. I holds connections. Database connections are still expensive to create, so you want to reuse them and database transactions are bound to the database connection, so you need multiple connections in order to process different requests in separate transactions.
Of course how big a connection pool should be is a completely different and rather complex question.

Related

Does UniData only allow one command or query per connection at a time?

Does UniData (Rocket U2) only allow one query or command to run at a time per connection?
I know each connection has a process or two (udapi_server/slave/etc. I believe), and we pool connections via UniObjects connection pooling. I know there have been optimizations to the UniRPC service in recent releases allowing threaded connection acceptance, but my suspicion is that even with that only one query is executed at a time on each connection synchronously.
i.e. if you have a maximum of 10 pooled connections and 10 long running queries, nothing else is even starting until one process completes its query - even if they are all I/O bound and CPU idle.
In connection pooling the process using the connection needs to finish prior to another request being accepted and using the same CP process. Connection pooling is ideal for small requests. Large queries returning the entire result set at once will tie up the CP process, and cause other requests for a connection to queue up.
Ian provided one possible solution, and I expect there are many ways you could break up the request to smaller requests that would not tie up the connection pooling licenses for prolonged periods of time.

Weblogic Stuck thread impacts other runnable threads in it

I am using Weblogic 10.3.6 with 8 managed servers configured with session timeout as 600 seconds. I have an issue with my application that when a session gets timed out in 600 seconds(I am receiving as STUCK alerts which is also configured) I am facing slowness in my application. My question is,
Will all threads be impacted because of one STUCK thread(STUCK thread
was due to DB transaction timeout)
I assume it will not be, but wanted to confirm.
Depends on your application. In general no, but if for example the stuck thread is holding a lock on an object (database, file, etc.) called by other requests, these may be affected too. Also, depending on what the stuck thread is doing, it may use excessive resources (cpu, memory, disk, etc.). I suggest to investigate why the thread is taking so long and if it's possible to

Multiple open sql connections

On a single page load I see several connections open. Although there are a at least 20 calls to the database, I see around 8 connections open before slowly dropping off. Each call is wrapped in a using statement, uses OpenStatelessSession and a singleton factory for nhibernate object. Shouldn't I only see a single connection open or is this normal behavior? I'm concerned because this is a high traffic site.
Each session always runs on a separate connection. If your site is exhausting the connection pool under load, you can switch to a session-per-request architecture, but that will of course consume more memory and CPU cycles due to the increased size of the first level cache.

How to determine buffer size

Let me explain what information I need for this:
I have several concurrent users hitting the same record at once. This means, there will be some queuing and locking going on, on the db end. How big is this buffer? Can queue and locking hold for 200+ concurrent users?
How can I determine the size of this buffer in our setup? Is there a default setting?
There is no query queue ("buffer") in the database.
Each concurrent connection to the database can have one query in flight. Other queries cannot be queued up behind it*.
Your application probably uses an internal connection pool, being Rails, so you can have however many queries waiting as you have slots in the connection pool.
If you have an external connection pool like PgBouncer proxying between your app and PostgreSQL then you can have more queries queued because you can have a much larger pool size in the app when connecting to pgbouncer as pgbouncer connections are so lightweight. PgBouncer will service those requests on a smaller number of real connections to PostgreSQL. That effectively makes PgBouncer a query queue (though not necessarily a FIFO queue) when used this way. HOWEVER because those queries don't actually hit Pg when they're issued they don't take locks while waiting in PgBouncer. This could be important for some concurrency designs.
* OK, so you can send multiple semicolon separated queries at once, but not in series like a queue.

NHibernate ISessionFactory.OpenSession() does not open a database connection

I have NHibernate configured with Fluent NNibernate connecting to a PostgreSQL database.
I have a worker class that takes an ISessionFactory as a constructor parameter and consumes messages from a queue. For each message the worker process calls ISessionFactory.OpenSession() and it does some database processing.
When I add more worker processes the performance of the system remains the same which is odd.
After some more investigation I realized that all worker processes are using a single database connection. For example I would add 8 worker processes but on the database I can see only one database connection.
My understanding is that ISessionFactory.OpenSession() will open a new database connection unless the Connection Pool is full.
So is my understanding wrong or is this and issue with the Postgres NHibernate driver.
OpenSession does not open a database connection until needed, and it closes it (i.e. releases it back into the pool) as soon as possible.
By default the session will keep the connection open for the life time of a transaction and as Diego said, it only opens it when needed.
If you want to manage your own connections you can call
ISessionFactory.OpenSession(myConnection);