【发布时间】:2012-02-25 02:03:33
【问题描述】:
我正在编写一个 servlet,它通过访问和修改数据库中的某些表来处理每个请求。我希望与数据库的连接是线程安全的。我不想为此使用现有的库/框架(spring、hibernate 等)。
我知道我可以通过以下方式使用 java 的 ThreadLocal:
public class DatabaseRegistry { //assume it's a singleton
private Properties prop = new Properties();
public static final ThreadLocal<Connection> threadConnection = new ThreadLocal<Connection>();
private Connection connect() throws SQLException {
try {
// This will load the MySQL driver, each DB has its own driver
Class.forName("com.mysql.jdbc.Driver");
// Setup the connection with the DB
Connection connection = DriverManager
.getConnection("jdbc:mysql://" + prop.getProperty("hostname") + "/" + prop.getProperty("database") + "?"
+ "user=" + prop.getProperty("username") + "&password=" + prop.getProperty("password"));
return connection;
} catch (SQLException e) {
throw e;
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
public Connection getConnection() throws SQLException {
if (threadConnection.get() == null) {
Connection connection = connect();
threadConnection.set(connection);
return threadConnection.get();
} else {
return threadConnection.get();
}
}
private void freeConnection(Connection connection) throws SQLException {
connection.close();
threadConnection.remove();
}
}
每次调用getConnection() 时,都会将新连接添加到ThreadLocal 对象中,然后在释放连接时将其删除。
这是正确的做法还是应该 DatabaseRegistry 本身扩展 ThreadLocal<Connection> 类?还是有更好的方法来确保所有连接线程安全?
【问题讨论】:
-
我认为这不是一个好习惯。请使用连接池,它将保持可用连接的核心大小。如果您使用 ThreadLocal,则每个请求都将拥有一个连接,如果您的 Web 服务器被阻塞,则连接将不会按时释放。
标签: java mysql database thread-safety thread-local