>> I added a bunch more synchronized (mutex) blocks in my code to avoid
>> getConnection being called simultaneously from multiple threads (why
>> isnt that method synchronized anyway?) - so far so good... keeping
>> fingers crossed. Maybe should have just subclassed PGSimpleDataSource...
>I'm not sure why it needs to be synchronized. The attached test case (20
threads each opening and closing >connections as fast as possible) doesn't
show any problems for me. Does it fail for you? Is there a >particular
change that fixes it for you?
I'm not sure if it needs to be synchronized either. Most likely I'm running
into a JVM bug in my particular environment (Tomcat servlet). I adapted your
test case to run inside a servlet and it does not produce any errors.
In my app I'm using singleton class instance to handle all database
connections, sample code below. If I remove synchronized (dbManager.class)
blocks the bug is back with a vengeance...
final public class dbManager {
private static PGSimpleDataSource _ds;
// Our global instance
private static dbManager _dbManager = null;
/**
* Attempts to create a valid PG DataSource
*
* @return a boolean representing whether the DS was successfully
created
*/
private synchronized static boolean createDataSource() {
try {
synchronized (dbManager.class) {
_ds = new PGSimpleDataSource();
_ds.setServerName("myserver");
_ds.setDatabaseName("mydb");
_ds.setPortNumber(5432);
}
return true;
} catch (Exception ex) {
Logger.getLogger(dbManager.class.getName()).log(Level.SEVERE,
null, ex);
return false;
}
}
public synchronized static dbManager getInstance(String connString) {
if ( _dbManager == null ) {
if ( createDataSource() ) {
_dbManager = new dbManager();
}
}
return _dbManager;
}
/**
*
* @return returns a connection created w/ default initial credentials
and very little access rights
*/
public synchronized Connection getInitialConnection() throws
SQLException {
synchronized (dbManager.class) {
return _ds.getConnection("inituser", "initpass");
}
}
/**
*
* @param dbUser
* @param dbPass
* @return a connection if it can be created, null otherwise
*/
public synchronized Connection getNewUserConnection(String dbUser,
String dbPass){
try {
synchronized (dbManager.class) {
Connection userConn = _ds.getConnection(dbUser,
dbPass);
return userConn;
}
} catch (Exception ex) {
Logger.getLogger(dbManager.class.getName()).log(Level.SEVERE, null, ex);
return null;
}
}
}