我正在编写一个 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>
班级?或者是否有更好的方法来做到这一点以使所有连接线程安全?
我不认为使数据库连接线程安全是一种常见的做法。通常你想要的是:
- 序列化对 servlet 某一部分的访问,以便一次不超过一个 servlet 执行代码(例如,实现
SingleThreadModel
界面)。
- 锁定特定的表/表页/行,以便您可以对某些特定的元组进行操作(通过更改数据库隔离级别)。
- 使用乐观锁定来检测表中修改的行(使用表的某些引用属性来检查当前版本是否与表中的版本相同)。
AFAIK,典型用途ThreadLocal<Connection>
就是为每个线程存储一个唯一的数据库连接,这样同一个连接就可以在你的业务逻辑中的不同方法中使用,而不需要每次都将它作为参数传递。由于常见的 servlet 容器实现使用线程来完成 HTTP 请求,因此可以保证两个不同的请求使用两个不同的数据库连接。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)