I didn't use any framework since it's only a little project. Now I invoke connection.close() in the destroy() method of the main servlet. But there are some problems.
I don't know when servlet.destroy() is invoked...I thought when the browser is closed is the time it's invoked,but it seems wrong.
I found out that if I don't operate the page visiting my project,after some time,destroy() is invoked,then the connection will be closed.But the project is running some code that maybe periodically write to the database,that case a exception will be thrown.
Any solutions? And I want to know when the servlet.destroy() will be invoked.
That only works if you have one shared connection.
A better solution is to use the JNDI connection pooling capability built into your servlet engine. You want to use a connection in the smallest method scope possible and return it to the pool. You'll be able to serve more clients with a small connection pool that way.
Related
My question is about this answer here that seems to work for my case (tomcat). However I see that it uses a newSingleThreadScheduledExecutor(). In my case the periodical task that has to be executed could be long lasting and I want to make sure that it will not block my web site until it has completed (run as a separated Thread). In addition I want to make sure that my task Runnable will be able to share mySQL connection pool (through hibernate) that the web site is using.
So, is that still the correct approach or do I have to use something else?
I want to make sure that it will not block my web site until it has
completed (run as a separated Thread)
The HTTP connector thread pool and the thread pool allocated to run timer tasks are different. They are not dependent on each other and will not block your website.
In addition I want to make sure that my task Runnable will be able to
share mySQL connection pool (through hibernate) that the web site is
using. So, is that still the correct approach or do I have to use
something else?
Configure a common connection pool using a framework like commons DBCP and lookup the resource on the JNDI. Once you lookup that DataSource and the work on the connection has terminated, return the connection back to the pool.
The approach is fine.
I have used MySqlDataSource for in jdbc connectivity.I have used following code
MysqlDataSource d = new MysqlDataSource();
d.setUser("user");
d.setPassword("pass");
d.setServerName("hostname.com");
d.setDatabaseName("db");
Connection c = d.getConnection();
Also i have searched there is an option of Configuring a MySQL Datasource in Apache Tomcat.
Is there any performance difference between these two? which one is best to use?
Configuring Datasource in tomcat will help you to share same data source between applications running in same tomcat. that Datasource will be managed by container (tomcat in your case).
while the Datasource created in code will be created by your application and can be used by that application only.
So if you have multiple application running on tomcat and accessing same data source, that configuring Datasource in tomcat will be good approach and have performance factor because only one data source is created and not having separate connections for each application
But if you have only single application that the first approach you have used is good one
They both use the internally the same driver, i dont think the performance is much different here, i guess if you need to access teh database only at that place and the enduser isn't supposed to use his own authentication you may use it directly from java, but if you will need the connectivity on different places it could be helpful to configure this using apache configuration, specially that if anything changes like database server, user name or whatever you don't need to get in the code to change it, this could be very important if end users have to set their own configurations.
The improvement of configuring a pool of Connections (as the one provided by tomcat) is mainly that you will actually create and close a lot less of connections.
When using a pool, when you request a Connection to a pool it will look if it has any connection already created and available for reuse and, if it has, it will provide you with it (instead of creating a new Connection, which is a heavy operation). You must still close() a Connection provided by Tomcat so Tomcat knows that it can now reuse when it is requested again.
Additionally, the advantage of the pool is that your code does not need to know the configuration data for the Connection. He just requests a Connection from a given pool and the sysadmin configures it, allowing for greater flexibility (the sysadmin does not need to know how to configure your app, just how to configure the Tomcat which is fairly more standard).
I am using Glassfish 3.1, JEE6 JPA Annotations, Hibernate provider and Derby database in my (simple) application. I seem to be having a lot of difficulties with connection pooling. Basically, my application worked fine without security, but now that I've create a security realm, I'm finding that I run of of connections no matter what size I set the pool to. Obviously, there is something that I'm doing in my code that means the connection is not being returned to the pool after the servlet request finishes.
I've seen various posting and advice on StackOverflow and have tried them all...nothing seems to work.
What I would like to know is this...How do I get logging and trace information out of Glassfish? I need to find out why it is not returning the connection to the pool. This way I hope to be able to find the source of the problem.
Many thanks!
Its always the first guess, that connections are not returned to the pool due to lack of cleaning up.
Make sure that:
close all connections you open
close all EntityManagers that you used
in every Path.
It is good practice, do
use
try
{
//open
//work
}
catch
{
//exception handling
}
finally
{
//close
}
anywhere where you handle those situations.
Side Note:
Static Analyzers like findbugs/sonar are able to detect those situations.
I'm doing some work on a JSP site that was coded very badly. For every single database call the original programmer opens and closes a database connection. I'm adding in some new database operations and I would like to do things a little bit better( something like hibernate will come later when more of the site can be rebuilt ). I was thinking of creating a single database connection when a session starts ( after logging in ), storing it in the session object and then closing it in session listener end of session handling function when the session closes. Is this a sound strategy? Thoughts?
I was thinking of creating a single database connection when a session starts ( after logging in ), storing it in the session object and then closing it in session listener end of session handling function when the session closes. Is this a sound strategy? Thoughts?
No. Create a container managed connection pooled data source and get it by JNDI on webapp's startup.
How to create the data source depends on the container in question. In case of for example Tomcat 6.0, you can read it up here: Tomcat JNDI Resources HOW-TO - JDBC Data Sources. In case of for example Glassfish 3, you can do it in the webbased admin console on http://localhost:4848.
Here's how you can finally get it from JNDI:
DataSource dataSource = (DataSource) new InitialContext().lookup(jndiName);
// ...
You can call getConnection() on it. It's sufficient to get the data source only once during webapp's startup, for example in a static initializer block of your database connection manager or perhaps in a ServletContextListener.
The connection should always be acquired and closed in the shortest possible scope. Get it inside the try block where you're executing the query and close it in the finally of the very same try block. Do not keep the connection open longer than necessary. The connection pool will take care about keeping them open, so the performance is already greatly improved that way.
Without commenting on your idea (because I've never done it that way so I don't know for sure), I can say that I've always seen it done something like this (see accepted answer):
How to reuse the same connection with a Spring's JdbcTemplate?
For starters you use a Common DBCP's PoolingDataSource instance stored in your ServletContext (or "application scope" in JSP parlance).
Ideally I would look to migrating to Spring (or Guice or similar).
Ok imagine this situation. I make a change to a pl/sql module, recompile it and everything is fine. No errors.
I then try to access a GUI screen on an application that runs on Tomcat. The screen calls a pl/sql module in an oracle database.
When i submit the form which should have called that pl/sql module for processing the data, i get this error
ORA-20001: ORA-06508: PL/SQL: could not find program unit being called
I checked all packages in $USER_OBJECTS and there is nothing with a status of INVALID.
I restarted Tomcat and then it starts working. Does this mean that when i recompiled the package the first time i effectively removed some cached reference to the package which Tomcat was using?
The connection to the database is via JDBC and DBCP connection pools. Does the recompile maybe invalidate the connection?
This issue is with the JDBC connection pools and is an issue you get with all app servers using JDBC connection pools, not just Tomcat. The connection pools will keep a number of connections open in the pool ready for the next request. If a PL/SQL package has been referenced by the connection and is recompiled then the next call to that package will raise an ORA-06508 error. This will affect packages anywhere in the call stack - not just the package you called directly.
To resolve this some app servers (like Weblogic) have a test method that is called periodically. If the test fails the connection is removed from the pool or refreshed in some way. I'm not sure what mechanism Tomcat has.
Another way to address it is to call dbms_session.reset_package as the first method call in your JDBC call. This will clear the package state from you're session. This approach isn't recommended as it has a performance overhead plus any package-scoped variables are reset so package initialisation blocks need to be called again - another performance hit.
If you've got the issue and you haven't got a way of dropping bad connections you'll need to reset the whole connection pool as any connection in the pool will suffer from the same exception.
The screen calls a pl/sql module in an
oracle database.
No, it doesn't. Assuming you're running a servlet based web-app on Tomcat then your browser sends a request to Tomcat, which invokes the relevant servlet and then some java class in the web-app will execute a pl/sql program as a CallableStatement.
The key to this is how the java class executes the CallableStatement and whether it retains a reference to it or prepares it each time it executes it. Can you shed any light on this?
Edit:
I beleive the Oracle JDBC driver is capable of performing statement caching, which may be causing the problem. Have a read of the driver docs to get more info.
The error you are getting usually indicates that the stored procedure/package either:
1) doesn't exist by the name you are trying to call it with (from your Java class)
2) is missing a grant EXECUTE privilege to the user (defined by the JDBC connection) that is trying to execute it
3) is missing a synonym, if it is being executed via its name only (i.e. without a schema prepended)
4) is being called without the correct number and types of parameters