We have pooling concept in stateless EJB. What is the advantage of using
pooling? My understanding is that it will save time in object creation.
Is this right? If yes, is there a significant difference in performance in creating
the object or getting it from the existing pool? Does the pooling serve any other purpose
than this?
Pooling can be usefull for sharing limited resources (e.g. database connections) and re-using objects that are expensive to create and/or destroy. When combined with an EJB, it can limit the load on the overall system which is very usefull when you run a server. According to the accepted answer in a similar question, it also helps with thread-safety.
An EJB can be expensive to create (or setup) when various resources and other EJB's are injected (with annotations), which, in my experience, is a common case. However, it appears that for example JBoss repeats this process even for pooled EJBs (see the answer from Tom Anderson in the similar question).
If a common EJB in a pool is often injected in other EJBs, the other EJBs will have to wait for a common EJB to become available when the system is really busy. The common EJB in a pool is then acting as a shared limited resource. The drawback is that you can get time-out exceptions (after for example 50 seconds) at unexpected places when a common EJB is not available (sometimes caused by a hickup in the infrastructure).
I have some experience with a JBoss server that has that pool mechanism for stateless EJBs in place. Within that JBoss server there is a common EJB that uses a database connection frequently. If a huge amount of work enters the system all at once, the load will be high but limited by the pooling mechanism. If the pooling mechanism limits the maximum load too much, the maximum load can be increased by increasing the maximum pool size.
Related
I am creating an application that will use a connection pool for database connections and I want to ensure that only one connection pool is created for the whole application to use. I was going to create a singleton to ensure there could be one connection pool ever opened, but many people suggest avoiding singletons. What are my alternatives, and what would that look like to the clients calling my connection manager?
If you are running standalone application , I dont see an problem with Singleton. It is purely depends upon how you are ensuring it is single instance.
IMHO Enum is the best of creating SingleTon . And Off course , I assume you are handling proper synchronization on your methods to avoid same connection shared multiple clients and unwanted usecase
You dont need to reinvent the wheel , you can use Apache DBCP Connection Pool and the sample
One answer from SO
If you are running in Application servers , then singleton is overkill . In App servers Singleton is not guarantee due to clustering. It is guarantee only per JVM . It is advise to use the datasources for the connection pool.
I'm new to java in web application design and I'm getting surprised how many things I don't now.
In particular I'm having problems in understending how servlet containers manage resources like connection pooling classes.
Assuming that I choose a pooling library (let's say c3p0), I read that there are many ways to use and manage the connection pooling classes.
For instance in many examples I saw that a certain class (let's say ComboPooledDataSource) is instantiated in the init() method of the servlet and here I'm getting a bit confusing. I mean, I think that a connection pooling system must exist and have a separate life with respect to all the servlets that will need a connection, otherwise it make no sense. So I think that the class below may be a Thread that is started once from the first servlet that call the init method and then it continues to exist until someone doesn not interrupt it. Is that correct? If not how does it work?
Anyway once I start this class , is it shared among all the servlets in the context (I mean all the servlets that call it in the init method)?
Other examples set up the connection pooling system as a resource by for instance defining it in the context.xml and then any servlet that want a connection just have to access it via JNDI (JNDI is correct?). What i understood (or I think to) is that in this case the thread that will execute the pooling system is started when the application is started and each servlet can access it when it wants to. Is that correct?
In this case can I modify the connection pooling system properties by a servlet or a background thread runtime? (for example if I want to change the number of connections as a function of the statistics on the number of requests and so on)
If I want to create different pools (for example I want to subdivide the database access to N different databases or I want to access using different usernames ) do I need to create as many resources as are the different kind of connection I want?
Is there a "better" way among these two or they are equivalent?
It comes down to ease of use of the webapp and (Tomcat) server maintenance.
You describe 2 use cases:
a connection pool used by one webapp
a connection pool shared between webapps
The first case is suitable for "ease of use": you can drop the war-file in any Tomcat server and it will work (e.g. Jenkins delivers such a war-file) since the webapp contains all the code needed to access a database. No need to change the configuration of the Tomcat server and restart it.
If I can, I like to deliver these kind of war-files since less things can go wrong (e.g. no clashes with configuration for other webapps). You can take it a step further by delivering Tomcat embedded with an application (so you don't need a Tomcat server to start with, an example project is here).
Note that opening a database connection pool (preferably via ServletContextListener.contextInitialized, not a servlet) and closing it (via contextDestroyed) does not involve starting and stopping a thread. The pool implementation may decide to start a background thread (e.g. to remove idle and/or abandoned connections), but it does not have to.
The second case is suitable for several webapps that share a common ground. For example, if several webapps all running in the same Tomcat server all use the same database, it saves time and effort if the Tomcat server already has a connection pool available for the different webapps (via JNDI). The Tomcat server can contain the JDBC driver software and connection pool software in the "lib" directory and configuration is done once in the context.xml of the server. If the database changes or different (patched) software components are required, only the tomcat server needs to be updated and all the webapps can remain the same. In this case, updating the Tomcat server instead of each webapp is a lot easier.
The second case is also more suitable for monitoring: there is a good chance you can monitor the connection pool via JMX. This kind of monitoring may not be available in the first case.
Changing "the number of connections as a function of the statistics on the number of requests " is not needed with connection pools: you set a maximum amount of connections to use and a timeout to remove idle connections. The connection pool will then grow and shrink with the number of requests.
Subdividing the database access to N different databases would require a different connection pool for each database, unless this is "read-only" in which case you could also use a load-balancer.
Access using different usernames is a bit tricky. I read in another question (which I cannot find anymore, sorry) that you can change the schema during runtime, but changing username/password might require a new connection in which case connection pooling is out.
Are you using Tomcat to run your servlets? Tomcat 7 has a new pooling solution that you could investigate. Tomcat also includes the dbcp libraries you can use them by setting the factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory". The DBCP pools are self managed and you can define the configuration values in the context.xml file I am not aware of how to change these values on the fly. I believe the Tomcat 7 pool use the same configuration as the DBCP with a couple of added options to make the conversion between the two simple. We use DBCP in all our applications and have not experienced problems so I have not used the Tomcat 7 pooling. I am thinking you would need to create many pools to handle most of your requirements.
(1) Okay I am pretty confused about the threading model of JAX-WS Java web services. I read they are not thread-safe. How are they supposed to serve multiple parallel requests then? Given that its always known (mostly) they are going to get called from multiple clients at the same time.
(2) And does the app server create a new instance of web service for each request (like it maintains a pool of stateless session beans, assigns one out for a request and once the request completes, it is returned to the pool). can you configure that pool size in app server console (GlassFish or JBoss or WebSphere).
(3) And I also found out about #Threadsope annotation here which creates new thread per request..
http://jax-ws-commons.java.net/thread-scope/
Is that a good option? I am sure people are solving the thread-safety and parallel requests issues in some other standard way - please advise.
An application server contains a pool of beans.
When working with stateless session bean, it is not guaranteed you will get the same instance across working with the session.
However, since as I mentioned, the beans are managed by a pool, holding a state in them, is a bad idea.
I don't think that EJB beans have anything to do with what your need, though.
Pay attention that in the example you provided, Both DataService and the connection are created per request. This is a bit expensive.
I would consider using the ThreadLocal API only for the connection, and have it obtained from a connection pool.
You can implement these on your own, by reading about ThreadLocal and by reading about DB connection pools.
To conclude - I don't think EJBs are relevant here.
Don't hold both your service class and the fields at the thread local, but only the necessary fields you will allocate per request. (in the example you showed - it's the connection)
I have been looking into connection pool options and it is somewhat unclear to me what the differences in Tomcat JNDI connection pool approach is, compared to the Spring/Hibernate solution to the same.
Whilst it's possible to achieve the pooling using either 1, 2, the specific application we have would lend itself better to us using Tomcat given the constraints we have.
Reading about, there is some suggestion to just stick with Spring/Hibernate.
Are there any notable differences worth mentioning between each approach? What are other's personal experience of one or the other (or both) - I have successfully been using Spring/Hibernate for years now.
The two approaches are complementary, not mutually exclusive. In production systems, the likes of Spring/Hibernate will obtain a reference to the connection pool from the appserver, in the form of a javax.sql.DataSource, usually by looking for it on the JNDI tree. It generally considered to be the appserver's "job" to manage the connection pool and its connections.
Remember, JNDI is just a place for registering objects for sharing, it does in itself mandate any given connection pool mechanism. The app server creates and configures the pool, and the applications (via Spring/Hibernate/whatever) use it.
It's just as valid, however, for the applications to configure and manage the connection pool themselves. This does mean a bit more work for the application, though, with less reliance on the appserver.
I need to implement a pool of Sessions that are returned by an external system,
so that I can reuse them quickly as soon as one is needed (creating a Session takes a while).
I've worked with datasource to create a pool of database connections (DBCP from Apache), and it was
an implemented solution.
What do we use in a general case to pool arbitrary objects, and are there implemented solutions, ie objects, not interfaces, to deal with the task painfully?
Second question would be, how do we test whether the Session is alive ? Is there a specific method that we override in the Object pool, that queries the Session's own methods?
The third, VERY IMPORTANT question, would be, should that object pooling object be static? A bundle of objects I extract from the system must be shared among different web applications. So, say, we extract 5 Sessions. App A queries the POOL and gets the first available Session. Now there are 4 Sessions left. Another App B starts and queries THE SAME POOL. etc The pool is shared. Among different instances of the same web app, running on the same machine.
For a generic pool of objects,
you have an Apache Commons
project for that.
For testing
that a session is alive, there are
different ways, but many of them are
unreliable. And the reliable one
(doing a query on dual) is slow.
You can have a look at c3p0,
which has that feature built-in.
As long as your many webapps are in the same WAR file, I think you'd be OK to use this static pool object. Although, personally, I prefer singletons over static objects that have anything more than utility methods and constants.
In general, I'm a big fan of Hibernate... have you considered using it for your application? You can still make plain SQL queries through it, and it handles your pooling and caching for you.
If you are using a J2EE application server then consider building a component implementing the Java Connector Architecture (JCA). Each instance of the component accesses a single Session and you configure the container to create at most five (from your example) instances. The container manages the pool and the component's lifecycle. Additionally, all applications deployed on that application server share the component's pool.
If I remember correctly (its been a while) there is also a way to signal the container that an instance died. In this scenario, the container removes the dead instance and instantiates a new one.
Some non-J2EE application servers have support for JCA components so check into it even if you are not using a traditional J2EE container.