The application I modified is a basic batch maintenance JDBC type of stand-alone application that reads a text file and updates a database. In order to speed things up, the application was parallelized (if that is a word).
The problem was that the DB2 java.sql.Connection object (which was being retrieved from a custom factory) was not thread-safe. So I opted to use an individual Connection per thread. But how to implement this strategy?
I could have used a connection pool (FOSS or rolled) to help out, but there were a bunch of reasons why I didn't, here's a sampling:
- The app is small and lean. Adding 3rd party pooling would be considered bloat, writing one myself would be a waste of time.
- No sharing benefit; one app runs per JVM. If the system were deployed on an app server, where multiple apps could benefit from the same pool, the centralized management might be worth it.
I chose to wrap the Connection in ThreadLocal instead. Then redirect all calls for a connection (in the factory) to ThreadLocal.get().
The class snippet below doesn't really work but it illustrates the point.
public static Connection getConnection() {It worked like a champ.. every thread that called getConnection() got a different Connection and the threads could do their work independently.
return (Connection) conn.get();
}
private static ThreadLocal conn = new ThreadLocal() {
public Object initialValue() {
String driverClass = "whatever";
try {
Class.forName(driverClass);
Connection con =
DriverManager.getConnection("connectionURL",
"user", "password");
con.setReadOnly(true);
con.setAutoCommit(false);
return con;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
};
(http://mattfleming.com/node/118)
No comments:
Post a Comment