Is unwrapped connection reused? - java

I have a spring component like following:
#Component
class FooComponent {
#Autowired
private DataSource dataSource;
public void execute() {
try (SQLServerConnection connection = dataSource.getConnection().unwrap(SQLServerConnection.class)) {
// some logic here with connection
}
}
}
I have to unwrap the connection because I'm using some API from Microsoft's JDBC driver (it throws exeption if I'm just passing dataSource.getConnection()).
So my question is:
I'm correctly getting the connection in execute method? Can that piece of code cause "connection leaks"?
I'm asking this because at some point I saw in logs a error like: Could not get JDBC Connection; nested exception is org.apache.tomcat.jdbc.pool.PoolExhaustedException. (I'm not asking how to solve this error or what it means)

So my question is: I'm correctly getting the connection in execute method?
No, the pool returns connection proxies rather than real ones (See ProxyConnection).
And the proxy's close method is "overridden" to return the connection to the pool:
if (compare(CLOSE_VAL,method)) {
if (connection==null) return null; //noop for already closed.
PooledConnection poolc = this.connection;
this.connection = null;
pool.returnConnection(poolc);
return null;
}
}
But when you do
try (SQLServerConnection connection = dataSource.getConnection().unwrap(SQLServerConnection.class))
the close method called on real connection, not on the proxy. The connection is not returned to the pool and eventually the pool throws PoolExhaustedException.
Here is how it can be fixed:
try (Connection connection = dataSource.getConnection()) { // proxy is returned to the pool
SQLServerConnection c = connection.unwrap(SQLServerConnection.class));
// Work with SQLServerConnection
}
Also remember that you should leave the unwrapped connection in the same state as you acquired it

Related

com.mysql.cj.jdbc.exceptions.CommunicationsException: The last packet successfully received from the server was XXXXXXXXXXXX milliseconds ago

I have a spring boot application that does not use connection pool and we didn't want to open a DB connection at every request
So, here is what we have in a class called MySQLService which has methods with DB queries:
#Autowired
#Qualifier("mysqlDB")
private Connection connection;
This connection object is always used in all of the methods with queries.
In MySQLConnection class,
#Bean(name = "mysqlDB")
public Connection getConnection() {
Connection connection = null;
try {
Class.forName(mysqlDriver);
LOGGER.debug("get mysql connection...");
connection = DriverManager
.getConnection(jdbcUrl,
user, password);
} catch (Exception exception) {
LOGGER.error("ERROR :: {}", exception);
}
return connection;
}
}
So, we are never really closing the connection, it is being managed by spring context but since we are not using JDBCTemplates, it does not get closed. We have autoreconnect set to true in connection string.
In a day or two, we get the exception:
com.mysql.cj.jdbc.exceptions.CommunicationsException: The last packet successfully received from the server was 61,183,452 milliseconds ago.
I understand it is because SQL Server has connection lifetime set so it expires the connection but what is a way to handle this without using a connection pool
Schedule a ping to the MySQL Server every 6 hours or so, executing this query: select 1 from dual. For that, you need to enable scheduling:
#Configuration
#EnableScheduling
public class SpringConfig {
//...
}
then:
#Scheduled(cron = "0 */6 * * *")
public void schedulePingMySQL() {
// execute `select 1 from dual`
}
Anyway, using a connection pool is the recommended way. This case the code may look like:
#Autowired
private DataSource dataSource;
public void save (Dto dto) {
Connection con = dataSource.getConnection();
// finally, close the connection
}

EndToEndMetrics on pooled db connections: isolated or not?

A dba in my office proposed the following to audit db access (oracle):
Put the current logged in user in my application as a property on the db connection (java.sql.Connection).
public class ClientInfoProvider {
void enrichConnection(Connection connection, String userName) throws SQLException {
OracleConnection oConn = (OracleConnection) connection;
String[] metrics = new String[OracleConnection.END_TO_END_STATE_INDEX_MAX];
metrics[OracleConnection.END_TO_END_CLIENTID_INDEX] = userName;
oConn.setEndToEndMetrics(metrics, (short) 0);
}
}
public class AuditableDataSource implements DataSource {
...
#Override
public Connection getConnection() throws SQLException {
Connection connection = dataSource.getConnection();
clientInfoProvider.enrichConnection(connection, loggedInUserString);
return connection;
}
...
}
My main concern is that connections are pooled. Wil users not end up using the same connection? The last user which changes the properties of the connection might influence the other users that are already using this connection. Is this a correct assumption?
Using the Spring jdbc datasource, a jdbc connection lives only long enough to execute it's query. Once the query is executed and the resultset has been closed, the connection will also be closed and released to the pool to be used for another query.

How to use connection pooling

I am new in connection pooling.I have a created a connection pool in mysql that adds five connections.Now i want to know what is the application of connection pooling,i.e after creating that pool how to use that.. i am pasting my code here
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Vector;
import com.mysql.jdbc.Connection;
class ConnectionPoolManager {
String databaseUrl = "jdbc:mysql://localhost:3306/homeland";
String userName = "root";
String password = "root";
Vector connectionPool = new Vector();
public ConnectionPoolManager() {
initialize();
}
public ConnectionPoolManager(
// String databaseName,
String databaseUrl, String userName, String password) {
this.databaseUrl = databaseUrl;
this.userName = userName;
this.password = password;
initialize();
}
private void initialize() {
// Here we can initialize all the information that we need
initializeConnectionPool();
}
private void initializeConnectionPool() {
while (!checkIfConnectionPoolIsFull()) {
System.out
.println("Connection Pool is NOT full. Proceeding with adding new connections");
// Adding new connection instance until the pool is full
connectionPool.addElement(createNewConnectionForPool());
}
System.out.println("Connection Pool is full.");
}
private synchronized boolean checkIfConnectionPoolIsFull() {
final int MAX_POOL_SIZE = 5;
// Check if the pool size
if (connectionPool.size() < 5) {
return false;
}
return true;
}
// Creating a connection
private Connection createNewConnectionForPool() {
Connection connection = null;
try {
Class.forName("com.mysql.jdbc.Driver");
connection = (Connection) DriverManager.getConnection(databaseUrl,
userName, password);
System.out.println("Connection: " + connection);
} catch (SQLException sqle) {
System.err.println("SQLException: " + sqle);
return null;
} catch (ClassNotFoundException cnfe) {
System.err.println("ClassNotFoundException: " + cnfe);
return null;
}
return connection;
}
public synchronized Connection getConnectionFromPool() {
Connection connection = null;
// Check if there is a connection available. There are times when all
// the connections in the pool may be used up
if (connectionPool.size() > 0) {
connection = (Connection) connectionPool.firstElement();
connectionPool.removeElementAt(0);
}
// Giving away the connection from the connection pool
return connection;
}
public synchronized void returnConnectionToPool(Connection connection) {
// Adding the connection from the client back to the connection pool
connectionPool.addElement(connection);
}
public static void main(String args[]) {
new ConnectionPoolManager();
}
}
can any one help?
The purpose of connection pooling is to maintain a number of open connections to a database so that when your application requires a connection it does not have to go through the potentially resource and time intensive process of opening a new connection.
When an application requires a database connection it 'borrows' one from the pool. When it's done, it gives it back and that connection may be reused at some later point.
Once you have obtained a connection, you use it in your application through the JDBC (Java Database Connectivity) API.
Oracle's basic tutorial for using JDBC can be found at http://docs.oracle.com/javase/tutorial/jdbc/basics/index.html
Another thing to keep in mind is that alot of work has gone into developing connection pools already, and it probably is not necessary to reinvent the wheel, except perhaps as a learning excercise. Apache Tomcat's connection pool implementation can be used outside of Tomcat (for example, in a standalone Java application) and is fairly flexible and easy to configure. It can be found at https://people.apache.org/~fhanik/jdbc-pool/jdbc-pool.html
I would say the code is pretty self explanatory.
You create an instance of the pool, personally, I prefer to use a singleton, but that's another topic
ConnectionPoolManager connectionPoolManager = new ConnectionPoolManager();
Now, every body that wants a connection, is going to need a reference to this manager. When you need to, you request a free connection from the pool...
public void queryDatabaseForStuff(ConnectionPoolManager cpm) throws SQLException {
Connection con = cpm.getConnectionFromPool();
//....
Once you're finished with the connection, you pass it back to the manager...
try {
//...
} finally {
cmp.returnConnectionToPool(con);
}
Now. You might like to investigating a blocking process that will block the current call to getConnectionFromPool while the pool is empty, meaning that it will either throw an exception (if you want to include a time out feature) or a valid connection.
When re-pooling a Connection, you might like to check to see if the Connection has been closed or not and have some kind of revival process to ensure that the pool is awlays close to capcaity...
Please check this link for getting detailed answer - https://examples.javacodegeeks.com/core-java/sql/jdbc-connection-pool-example/
You don't need to recreate your Connection object pool , instead please use the libraries provided by Apache . Please be clear of the following :
1 - Why and what made you think of connection pool ?
2 - Use the following Apache commons-dbcp lib in your Maven project and then use the classes as per documentation .
3. Does this solve all your problems ?
ITs Better to perform the connection pooling via in built API
Like
DBCP or this.
Its always better let these API perform the connection pooling and programmatically creating and maintaining the connection pooling always painful activity.

Java Postgres connection limit exceeded

I am using Java 1.7 and Postgres via the Postgres JDBC drivers. The database connection will be used from a Web Service. In testing, I got the following error:
FATAL: connection limit exceeded for non-superusers
I solved the error by making my connection static, and, only creating once. My question is, is a static connection safe? Is this the right way to do this?
I am using the connection via a ConnectionFactory that looks something like this:
public class ConnectionFactory
{
String driverClassName = "org.postgresql.Driver";
String connectionUrl = "jdbc:postgresql://localhost:5432/dbName";
String dbUser = "user";
String dbPwd = "password";
private static ConnectionFactory connectionFactory = null;
private static Connection conn = null;
private ConnectionFactory()
{
try
{
Class.forName(driverClassName);
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
}
public Connection getConnection() throws SQLException
{
if (conn == null)
{
conn = DriverManager.getConnection(connectionUrl, dbUser, dbPwd);
}
return conn;
}
public static ConnectionFactory getInstance()
{
if (connectionFactory == null)
{
connectionFactory = new ConnectionFactory();
}
return connectionFactory;
}
}
Postgres JDBC driver is documented as thread safe and the connection can be used by multiple threads if so required. 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.
Connection pooling may be used anyway for performance reasons.
Sorry, original post didn't look at your code carefully. Wow. I still can't read. Anyway, third time's the charm. If your code is single threaded - then your fine. If it's multi-threaded, use something like the Commons connection pools to manage your connections. It looks like the driver is thread safe but the connection shouldn't be viewed as thread safe. So, once the driver is loaded you can safely call getConnection on the driver from multiple threads, but the connection shouldn't be shared across threads.

Custom java.sql.Driver Implementation Connection Handling

Currently, I load the below custom driver (TestDriver.java), get a connection, create a Statement, execute a query, gets the results and close the connection. I open and close a connection for each query. Is this common practice or is there an standard way to share the open connections?
public static void main(String[] args) {
Class.forName("com.sql.TestDriver");
java.sql.Connection conn = DriverManager.getConnection("jdbc:test://8888/connectme", props);
Statement stmt = conn.createStatement;
ResultSet rs = stmt.executeQuery("select * from table");
//loop through rs and pull out needed data
conn.close();
}
public class TestDriver implements java.sql.Driver{
private final TestSchema schema;
private Properties props = null;
static {
try {
DriverManager.registerDriver(new TestDriver());
} catch (SQLException e) {
e.printStackTrace();
}
protected TestDriver() throws SQLException {
schema = TestSchemaFactory.getInstance().getDbSchemaFromFile(SCHEMA_FILE);
//loads in and parses a file containing tables, columns used for business logic
}
public Connection connect(String url, Properties info)
throws SQLException {
TestSqlConnection conn=null;
//connect logic here
return conn; //will return an instance of TestSqlConnection
}
#Override
public boolean jdbcCompliant() {
return false;
}
}
Yes, it's more common to use a database connection pool. This will allow connections to be reused without the overhead or closing/re-opening. Here's a link to DBCP which is one implementation of a database connection pool: http://commons.apache.org/dbcp/
Ideally you should write a separate factory class (can be static)
say ConnectionFactory which returns a connection object.
Also I see that you are not using try/catch/finally block while creating
connection.I strongly suggest to close the connection in finally
clause otherwise you program may suffer from connection leak if any
exception is raised and causes abrupt behavior.
Ideally you should close the connection after your operation is complete in finally
clause.In web based application if you are using connections pool
then closing connection will return the connection back to pool and
will be available for use.

Categories

Resources