Java线程安全数据库连接

我正在编写一个Servlet,该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请求,所以保证了两个不同的请求使用两个不同的数据库连接。

以上是 Java线程安全数据库连接 的全部内容, 来源链接: utcz.com/qa/411092.html

回到顶部