I know that Java EE's session object can store complex objects, like a connection to a database.
I'm pondering how to implement a certain application for a programming practice, made with Java EE. My first option to use a connection pool, which is very easy with Java EE.
I'm wondering, out of curiosity, and also to properly justify the decision, what are the pros and cons of creating a connection to the database any time a client starts a session and storing it there, against the use of a connection pool.
Thanks a lot.
A resource pool will optimise the handling of the resource (your database connection) in a way your system can cope with it. Even though you can end up out of resources if you have a lot of opened connections.
That is more likely to happen if you store your database connection in the session context. Web applications don't need to be connected all the time to a database, that connection can be stablished at the beginning of a new operation and closed at the end. Using a resource pool you return your connection back to the pool when you no longer need it, so a new user (session in the web paradigm) can use that resource you have already released instead of creating a new one.
The pool will also handle the scenario in which some resources have been idle for a long time (no one has used them in a specific amount of time) and then it will release those resources.
When storing a database connection in the session you are never releasing the resource but keeping a permanent reference to it that will last as long as the user session does. You may not face any issues in a short time with that, specially if there are really few users connected at the same time. But in real world applications you will definitively find them.
Thus, storing a database connection in the session context is considered as a bad practice.
EDIT: I forgot to mention that should only store Serializable objects in the session so, if the application server decides to passivate a session, it can be persisted and restored when the application server decides to reactivate it. A database connection is not a Serializable resource.
Using a connection pool allows you maximize the usability of your connections. This means less connections = less memory = less sockets etc. The reason a pool is better than saving in a session is what happens if someone drops out unexpectedly? If you have a connection in your session, you risk keeping that connection alive for a long time, possibly indefinitely.
Related
Scenario:
There is something called FAN notification in Oracle Database, which is used for High Availability.
Whenever I will get this notification in my Java application I want to reset all the JDBC connections object available in my Connection Pool.
But the problem is, even if I reset the connection pool objects, there will be some JDBC transaction going on using old connection objects.
My question is, can we somehow change that (which is in use) connection object with the new object and copy or transfer the transactions to new connection object without any inflight transaction.
[update]: This scenario is handled between server and database using something called Grid Link. But I want to handle it in application end, by removing all the JDBC connection objects from connection pool, these connection objects will point to new database instance which is up and running.
If it is not possible please suggest me some alternative solution.
This question already has answers here:
How to manage db connections on server?
(3 answers)
Closed 7 years ago.
I have a Java server and PostgreSQL database.
There is a background process that queries (inserts some rows) the database 2..3 times per second. And there is a servlet that queries the database once per request (also inserts a row).
I am wondering should I have separate Connection instances for them or share a single Connection instance between them?
Also does this even matter? Or is PostgreSQL JDBC driver internally just sending all requests to a unified pool anyway?
One more thing should I make a new Connection instance for every servlet request thread? Or share a Connection instance for every servlet thread and keep it open the entire up time?
By separate I mean every threads create their own Connection instances like this:
Connection connection = DriverManager.getConnection(url, user, pw);
If you use a single connection and share it, only one thread at a time can use it and the others will block, which will severely limit how much your application can get done. Using a connection pool means that the threads can have their own database connections and can make concurrent calls to the database server.
See the postgres documentation, "Chapter 10. Using the Driver in a Multithreaded or a Servlet Environment":
A problem with many JDBC drivers is that only one thread can use a
Connection at any one time --- otherwise a thread could send a query
while another one is receiving results, and this could cause severe
confusion.
The PostgreSQLâ„¢ JDBC driver is thread safe. Consequently, if your
application uses multiple threads then you do not have to worry about
complex algorithms to ensure that only one thread uses the database at
a time.
If a thread attempts to use the connection while another one is using
it, it will wait until the other thread has finished its current
operation. If the operation is a regular SQL statement, then the
operation consists of sending the statement and retrieving any
ResultSet (in full). If it is a fast-path call (e.g., reading a block
from a large object) then it consists of sending and retrieving the
respective data.
This is fine for applications and applets but can cause a performance
problem with servlets. If you have several threads performing queries
then each but one will pause. To solve this, you are advised to create
a pool of connections. When ever a thread needs to use the database,
it asks a manager class for a Connection object. The manager hands a
free connection to the thread and marks it as busy. If a free
connection is not available, it opens one. Once the thread has
finished using the connection, it returns it to the manager which can
then either close it or add it to the pool. The manager would also
check that the connection is still alive and remove it from the pool
if it is dead. The down side of a connection pool is that it increases
the load on the server because a new session is created for each
Connection object. It is up to you and your applications'
requirements.
As per my understanding,You should defer this task to the container to manage connection pooling for you.
As you're using Servlets,which will be running in a Servlet container, and all major Servlet containers that I'm aware of provide connection pool management.
See Also
Best way to manage database connection for a Java servlet
Context
I have a RESTful API for a versus fighting game, using JAX-RS, tomcat8 and Neo4j embedded.
Today I figured that a lot of queries will be done in a limited time, I'm using embedded for faster queries but I still want to go as fast as possible.
Problem
In fact, the problem is a bit different but not that much.
Actually, I'm using a Singleton with a getDabatase() method returning the current GraphDatabaseServiceinstance to begin a transaction, once it's done, the transaction is closed... and that's all.
I don't know if the best solution for optimal perfs is a Singleton pattern or a pool one (like creating XX instances of database connection, and reuse them when the database operation is finished).
I can't test it myself actually, because I don't have enough connections to even know which one is the fastest (and the best overall).
Also, I wonder if I create a pool of GraphDatabaseService instances, will they all be able to access the same datas without getting blocked by the lock?
Crate only one on GraphDatabaseService instance and use it everywhere. There are no need to create instance pool for them. GraphDatabaseService is completely thread-safe, so you can not worry about concurrency (note: transaction are thread-bound, so you can't run multiple transactions in same thread).
All operations in Neo4j should be executed in Transaction. On commit transaction is written in transaction log, and then persisted into database. General rules are:
Always close transaction as early as possible (use try-with-resource)
Close all resources as early as possible (ResourceIterator returned by findNodes() and execute())
Here you can find information about locking strategy.
To be sure that you have best performance, you should:
Check database settings (memory mapping)
Check OS settings (file system)
Check JVM settings (GC, heap size)
Data model
Here you can find some articles about Neo4j configuration & optimizations. All of them have useful information.
Use a pool - definitely.
Creating a database connection is generally very expensive. Using a pool will ensure that connections are kept for a reasonable mount of time and re-used whenever possible.
Is there any way in java to do http connection pooling without using third party api like httpclient,http-commons etc..?
In my case i want to open a connection with url of particular servlet & my query string changes but whenever i open a connection.it open a new connection as i have seen doing
'netstat -anp | grep portno' which i dont want ?
String sendMessageUrl="http\://ip\:portno/contextpath/servlet/Servletname?parameter1\=¶meter2\=";
URL testURl=new URL(sendMessageUrl.replaceAll("&", name+"&")+surname);
HttpURLConnection httpConnection=(HttpURLConnection)testURl.openConnection();
httpConnection.connect();
if(httpConnection.getResponseCode()==200)
{
System.out.println("Success");
}
Here only parameter1 & parameter2 changes except that entire url remains same.
You pool objects when it is expensive to create those objects, for example database connections are expensive to create and therefore pooling makes sense. Without using a third party framework it's still possible to pool HTTP connections, after all a pool is simply a collection of previously created instances of a class.
At a minimum to create a class that manages connection pooling for HTTP you'll at least need to do the following:
Retrieve an instance from the pool (object in use)
Place the instance back in the pool (object no longer in use)
Size of pool
You might also need to look at the following as functionality that might be worthwhile on the pool:
Reconnect instances that have become stale
Maximum idle time, remember an idle connection is still consuming resources
Time a connection can be in use before throwing an exception
A way to validate the connection is valid, e.g. For a db connection a simple SQL is executed
There are many other things to consider however it depends on your exact requirements if your building it yourself. You should try it out and if you run into problems then ask SO for help on your specific issues.
You can use HttpURLConnection part of JDK. It uses a TCP connection pool under the hood
Just wondering if beginning a new transaction in Hibernate actually allocates a connection to the DB?
I'm concerned b/c our server begins a new transaction for each request received, even if that request doesn't interact with the DB. We're seeing DB connections as a major bottleneck, so I'm wondering if I should take the time narrow the scope of my transactions.
Searched everywhere and haven't been able to find a good answer. The very simple code is here:
SessionFactory sessionFactory = (SessionFactory) Context.getContext().getBean("sessionFactory");
sessionFactory.getCurrentSession().beginTransaction();
sessionFactory.getCurrentSession().setFlushMode(FlushMode.AUTO);
thanks very much!
a
According to the section 11.1. Session and transaction scopes of the Hibernate documentation:
A SessionFactory is an
expensive-to-create, threadsafe
object, intended to be shared by all
application threads. It is created
once, usually on application startup,
from a Configuration instance.
A Session is an inexpensive,
non-threadsafe object that should be
used once and then discarded for: a
single request, a conversation or a
single unit of work. A Session will
not obtain a JDBC Connection, or a
Datasource, unless it is needed. It
will not consume any resources until
used.
In order to reduce lock contention in
the database, a database transaction
has to be as short as possible. Long
database transactions will prevent
your application from scaling to a
highly concurrent load. It is not
recommended that you hold a database
transaction open during user think
time until the unit of work is
complete.
Now, to answer your question:
getting a Session does not immediately acquire a connection (the connection is lazy loaded)
but calling beginTransaction() will cause the load of the connection for the given Session
subsequent calls will reuse the same connection
Look at org.hibernate.impl.SessionImpl#beginTransaction() and go through the code for more details.
(Updated per Pascal Thivent's comment)
Each Session creates a database connection if there is a need for that - e.g. if a transaction is started. The connection is not opened with the mere creation of the session.
To overcome this, you can use a connecetion pool so that connections are reused. Or you can make sure (as it appears you did) that no transaction is started automatically.
(This discusses read-only transactions. Take a look.)