While running a Java application from NetBeans, and the application connects to a remote database, if we try to kill the application from NetBeans using the Stop button, will it cause a database connection leakage?
If so.. where should we set the properties to close all Database connections before killing the running instance of the application.
There are two sides where a connection can be leaked.
Within the Java software:
You really can ignore this because the application will be killed soon.
Within the database:
This will cause problems, BUT every single network server application will check if a connection breaks away and free resources.
So I don't think you will get problems, because the database will mark the connections as invalid and free all resources.
Related
We are using H2 started as database server process and listening on standard TCP/IP port 9092.
Our application is deployed in a Tomcat using connection pooling. We do a purge during idle time which at the end results in closing all connections to H2. From time to time we observe errors when the application tries to open the connection to H2 again:
SCHEDULERSERVICE schedule: Exception: Database may be already in use: "Waited for database closing longer than 1 minute". Possible solutions: close all other connection(s); use the server mode [90020-199]
org.h2.jdbc.JdbcSQLNonTransientConnectionException: Database may be already in use: "Waited for database closing longer than 1 minute". Possible solutions: close all other connection(s); use the server mode [90020-199]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:617)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:427)
at org.h2.message.DbException.get(DbException.java:205)
at org.h2.message.DbException.get(DbException.java:181)
at org.h2.engine.Engine.openSession(Engine.java:209)
at org.h2.engine.Engine.createSessionAndValidate(Engine.java:178)
at org.h2.engine.Engine.createSession(Engine.java:161)
at org.h2.server.TcpServerThread.run(TcpServerThread.java:160)
at java.lang.Thread.run(Thread.java:748)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:617)
at org.h2.engine.SessionRemote.done(SessionRemote.java:607)
at org.h2.engine.SessionRemote.initTransfer(SessionRemote.java:143)
at org.h2.engine.SessionRemote.connectServer(SessionRemote.java:431)
at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:317)
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:169)
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:148)
at org.h2.Driver.connect(Driver.java:69)
at java.sql.DriverManager.getConnection(DriverManager.java:664)
The problem occurs when the Tomcat connection pool closes all idle connection (unused) and one connection still in use is closed afterwards.
The next attempt to open a new connection fails, a retry is successfully after some wait time.
Under which circumstances does this exception happen?
What does the exception mean?
Are there any recommendations to follow to avoid the problem?
It sounds to me that H2 does a database close after the last connection has been closed.
When does the database close occure?
How can database closures been controlled?
Thx in advance
Thorsten
Embedded database in web applications needs careful handling of its lifecycle.
You can add a javax.servlet.ServletContextListener implementation (marked with #WebListener annotation or included into web.xml) and add explicit database shutdown to its contextDestroyed() methods.
You can force database shutdown here with connection.createStatement().execute("SHUTDOWN"). If your application needs to write something to database during unload, it should do it before that command.
Without the explicit shutdown H2 closes the database when all connections are closed, if some other behavior wasn't configured explicitly (with parameters in JDBC URL, for example). For example, DB_CLOSE_DELAY sets the additional delay, maybe your application uses that setting and therefore H2 doesn't close the database immediately, or application doesn't close all connections immediately.
Anyway, when you're trying to update the web application of the fly, Tomcat tries to initialize the new version before its old version is unloaded. If H2 is in classpath of the web application itself, the new version will be unable to connect to the database during short period of time when the new version is already online but the old version isn't unloaded yet.
If you don't like it, you can run the standalone H2 Server process and use remote connections to it in your web applications.
Another option is to move H2 to the classpath of Tomcat itself and configure the connection pool as resource in the server.xml, in that case it shouldn't be affected by the lifecycle of your applications.
In both these cases you shouldn't use the SHUTDOWN command.
UPDATED
With client-server connections to a remote server such exception means that server decided to close the database because there are no active connection. This operation can't be interrupted and reverted in the middle. On attempt to open a new connection to the same database during this process it waits at most for 1 minute for completion of this process to re-open the database again. This timeout is not configurable.
There are two possible solutions.
DB_CLOSE_DELAY setting can be used with some large value in seconds. When all connections are closed, database will stay online for the specified number of seconds. -1 also can be used to set an infinite timeout.
You can try to speed up the shutdown process, but you have to figure out what takes so much time by yourself. The file compaction procedure is limited to 200 milliseconds by default, it may take a longer time, but I think it shouldn't be that long. Maybe you have a lot of temporary objects or uncommitted data. Maybe you have a very high fragmentation of database file. It's hard to say what's going wrong without further investigation.
I have a few computers that are running a local script but need to be able to communicate information between them. I am using a MYSQL database on one of the computers with XAMPP to accomplish this.
Each computer repeatedly starts and kills the local script it is running which has a static database class which creates a connection using JDBC on initialization. They then use this connection to preform actions for about 10-15 minutes before the script is terminated and then restarted.
There are only 5 computers which have access to the MYSQL database and my max_connections is set to 151 but every once and a while I get a connection limit reached error and all my scripts crash.
I assume that MSQL database connection close automatically when the script is terminated because I can run the scripts far more than 151 times before this error occurs. Do I need to close the connections before I terminate the scripts? What could be causing this to occur?
Also, I can simply restart the scripts when this error occurs and they start back up fine. I do not need to go to phpMyAdmin and flush.
Check that you are disconnecting the DB when you finish using it. Some times it takes a while to auto disconnect the session.
You should always close the connection when you are done with it as a best practice. In Java if you neglect to close the connection then you will end up with an open connection; however, the documentation for PHP suggests an unclosed connection will be closed when the script completes: http://php.net/manual/en/function.mysql-connect.php
You can monitor the open connections via your MySQL Workbench or equivalent tool and find where they are coming from as well.
I have a very short Java application that just opens a connection to a remote MySQL database, reads some data, prints it, and exits. The most time-consuming part of the application is the database connection.
Currently I have only a single thread, and my only concern is to save the time of opening the connection.
I thought of several ways to make it faster, but it turned out they do not help:
Connection Pooling - doesn't help because the pool lives only only during a single run of the application. When the application is terminated, the pool is gone, and when I re-run the application, I have to re-open all the connections in the pool.
mysql-proxy - connects only to the local server: mysql-proxy for a remote MySQL server
TCP/IP server - I thought of holding a local TCP/IP server that will keep a persistent open connection and send it to a TCP/IP client on request. However, Connection objects cannot be serialized, so I have no way to pass the Connection object from client to server.
Any other option?
Generally connection to a DB is a most time-consuming operation. If the application is to be started and stopped then there is little that you can do.
Using connection-pooling in a web-server and call that by running your app which talks to the web server using JSON might be an option.
You said you have a very short application so your 3rd option might work if you put the database logic into you "option 3 TCP/IP server" and just forward the results to your connecting client. This is a typical application server pattern.
Another thing you should consider about network look up https://stackoverflow.com/q/3641155/1055715 which Marc B has mentioned in his comment.
It turns out the best solution is to use mysql-proxy with a script that handles connection pooling (a combination of my first two options). I found one such script here:
http://forge.mysql.com/tools/tool.php?id=151
It was probably written for an older version of mysql-proxy, so I had to fix it (if anyone need the fixed version - write me).
It works like a charm - I run the exact same application as before, the only change is in the connection string: instead of connecting to "qa-srv:3308" (the remote server) I connect to "127.0.0.1:4040" (the proxy server).
I have a stand-alone Java windows application developed based on Swing. It connects to a MySQL database for data storage. In case the database connection fails, I am getting a link failure exception from the MySQL JDBC driver (MySQLNonTransientConnectionException). I don't want to re-instantiate my database connection object or the whole program in case such a link failure issue happens. I just want to tell the user to try again later without having to restart the entire application. If the user is asked to restart the entire application, that would probably give a negative impression on the quality of the program. What do you think would be the preferred way for a standard java application to fail-over after such a database link failure without having to re-instantiate all the communication objects? Thanks in advance.
Use a Connection Pool (such as C3PO or DBCP). Your application takes the Connections from the pool, executes the statement(s) and puts the Connection back into the pool. The pool can be configured to test the JDBC Connections. For example, if they become stale, they can be automatically reinstantiated by the pool.
If your application takes the Connection from the pool, it will be a valid Connection. Let the pool handle the management of valid/invalid/stale JDBC Connections.
I've been building a test application that works with a database that up until recently has been without a UI. I'm adding one now. Problem is, the JFrame is launched in another thread and I need my database connection to close when that thread closes (when the UI closes, I should say). How do I do this?
Also, what happens to the application's database connection (in this case an embedded database) if the application crashes or is forcefully closed? I hear that unclosed connections cause resource leaks. Anything I can do to clean up if this happens?
You may add a shutdown hook to your runtime system. It's a thread which will be fired on closing the virtual machine. In the thread you can close all db connections and other critical resources.
The WindowClosingEvent will be fired if a User attempts to close your JFrame. So in this method you can close your connection.
Your DBMS uses a pool of connection. If you don't close your connections properly, this connection pool is filled with unused connection.
It's bad if the pool is full and a new connection is needed. The application won't work. Either the user waits and tries it one more time (while he's waiting, one connection could be closed or killed) or the database is restarted manually so all connection are lost.
The DBMS closes all unused connections after a predefined time. Which parameter does specify this time, you'll find it in your DBMS manual.
In addtion to your comment: You cannot assure that you have enough time to clean up your connections. Probably your application is killed by your sytem or whatever. So: Try to clean up your connection as soon as possible.
Unused connections can only be removed by the DBMS once you've lost the connection object.