I have implemented a very simple ConnectionPool in Java. It has no fancy features, just get/release connection methods.
How can I test it is working?
I know there are plenty of connection Pools ready to use out there, which are much more reliable than what I'll do, but I am just trying to practice to understand how connections Pool work.
Thank you!
Here is the code in case it helps:
public class ConnectionPoolImpl implements ConnectionPool {
private Vector<PooledConnection> connections; // The connections container
String url;
String username;
String password;
/**
* Instanciates a new MySQLConnectionPool
* @param nbConnectionsMax
*/
public ConnectionPoolImpl(String DBUrl, String username, String password){
this.connections = new Vector<PooledConnection>();
this.url = DBUrl;
this.username = username;
this.password = password;
}
/**
* Returns a connection from the pool, if some are available, or create a new one.
*
* @return the connection.
*/
public Connection getConnection() throws SQLException {
synchronized(this.connections){
// Checking if there is an available connection to return
for(PooledConnection c : this.connections){
if(!c.isUsed()){
c.setUsed();
return c.getConnection();
}
}
// If there are none, open a new one and return it
Connection conn = DriverManager.getConnection(url, username, password);
PooledConnection pConn = new PooledConnection(conn);
pConn.setUsed();
connections.add(pConn);
return pConn.getConnection();
}
}
/**
* Releases a connection to the pool.
*
* @param con the connection to release.
*/
public void releaseConnection(Connection con) throws SQLException {
synchronized(this.connections){
for(PooledConnection c : this.connections){
if(c.getConnection().equals(con)){
c.se开发者_Go百科tFree();
return;
}
}
}
}
}
And my PooledConnection.java:
public class PooledConnection {
private Connection conn;
private boolean used;
public PooledConnection(Connection conn){
this.conn = conn;
this.used = false;
}
public void setUsed(){
this.used = true;
}
public void setFree(){
this.used = false;
}
public boolean isUsed(){
return this.used;
}
public Connection getConnection(){
return this.conn;
}
}
You could test that
- getting a connection when the pool is empty gives you a connection
- getting a connection when a connection has already been got and not released gives you another, different connection
- releasing a connection doesn't throw any exception
- getting a connection after one has been released gives you the same connection
Note that such a unit test would need a real database, with a real user and password to test. You could make your connection pool depend on a DataSource, and build your ConnectionPool using a mock DataSource returning mock Connections, in order to be able to test the class without depending on a real database.
For an integration test, you could use dbUnit to load the database with prepared data and then write tests that query the database.
For an unit test, you might consider using a mocking library such as Mockito to ensure that you get the behaviour you expect. No database necessary in this case. [EDIT: However, due to the static method calls like DriverManager.getConnection(), this will require some refactoring and/or dependency injection.]
By combining both the unit tests and integration tests (and mix in some multi-threaded unit tests), you can go a long way towards testing your work.
Industrial strength connection pools have the ability to check connections by making a connection and executing a simple SQL query (e.g. "SELECT 1") to ensure that connection is viable before giving it out. Yours does not.
I don't see where you can initialize the connection pool with a fixed number of connections. The whole point of a connection pool is to amortize the cost of creating a connection over all clients.
I'd worry about the design of your connection pool.
As for testing, just start writing unit tests. Since your pool will be shared, be sure to write some multi-threaded tests to make sure that it's really thread safe.
You should also test concurrency/scalability under load using multiple threads.
sometimes you might have configured the connection pool and the connections got created successfully.
but
how do you say all the connections are being accessed? sometimes only one connection may be being used repeatedly due to a configuration issue. therefore, you can clarify that by executing this query in a loop (it is better if you can use a parallel process) select connection_id();
with connections that you created. if you have successfully configured the pool, you can see the different ids as the output.
精彩评论