简体   繁体   English

使用静态类/方法中的方法级连接的池化数据库访问是否安全?

[英]Is a pooled db-access using method-level connection in a static class/method safe?

have been a long-time reader here and now I`ve got a problem I can´t really get my head around. 我在这里已经是一个长期的读者,现在我遇到了一个问题,我真的无法理解。

For ease of access and to save object creation overhead I have a static class realizing database accesses. 为了简化访问并节省对象创建的开销,我有一个静态类来实现数据库访问。 The used JVM implementation is Tomcat and for connection pooling org.apache.commons.dbcp is used. 使用的JVM实现是Tomcat,并且用于连接池的org.apache.commons.dbcp。

I've read a lot about thread-safety, heap and stack here and elsewhere but I can`t get to a definitive conclusion if multiple method calls on my static class won't interfere with each other. 我在这里和其他地方已经读过很多关于线程安全,堆和堆栈的信息,但是如果我的静态类上的多个方法调用不会相互干扰,我将无法得出明确的结论。 Most topics I've read deal with instance methods while I use static ones which might have implications I overlooked. 我读过的大多数主题都涉及实例方法,而我使用的是静态方法,这可能会影响我的工作。

If I understood everything correctly, as the variables connection, statement, resultset are on the method level, each function call should have a unique reference on the stack to a unique object in the heap and it should not be possible that multiple method calls interfere with each other. 如果我正确理解了所有内容,那么由于变量连接,语句,结果集位于方法级别,则每个函数调用在堆栈上应具有对堆中唯一对象的唯一引用,并且多个方法调用不应干扰彼此。

Am I right or do I stand corrected? 我是对的还是我站得住脚的? Any help would be appreciated. 任何帮助,将不胜感激。

The (shortened) code is : (缩短的)代码是:

public class DBQuery{


private static String pathToDataSource = "";
private static javax.naming.Context cxt = null;
private static javax.sql.DataSource ds = null;


private static void getDataSource() throws Exception {
  if(pathToDataSource.equals("")){ pathToDataSource = Config.getParam("PathToDataSource"); }
  cxt = new javax.naming.InitialContext();
  ds = (javax.sql.DataSource) cxt.lookup(pathToDataSource);
}


private static Connection connect() throws Exception {
  if(ds==null){ getDataSource(); }
  return ds.getConnection();
}


public static Vector doDBquery(String querystring) throws Exception {
  Vector retVec = new Vector();
  Connection connection = null;
  Statement statement = null;
  ResultSet resultset = null;
  try {
    connection = getConnection();
    statement = connection.createStatement();
    resultset = statement.executeQuery(querystring);    
    ...
  } catch(Exception e) {
    ...
  } finally {
    myFinallyBlock(resultset, statement, connection);
  }
  return retVec;
}


// more methods like doDBInsert() following, hence closure in separate myFinallyBlock


private static void myFinallyBlock(ResultSet resultset, Statement statement, Connection connection) {
  try {
    if (resultset != null) resultset.close();
  } catch (SQLException e) { resultset = null; }
  try {
    if (statement != null) statement.close();
  } catch (SQLException e) { statement = null; }
  try {
    if (connection != null) connection.close();
  } catch (SQLException e) { connection = null; }
}


} //close class

Yeah, you are right inside method there is no concurrency problems , until you are using shared variables inside it, in other words "Stateless objects are always thread-safe." 是的,在方法内部就没有并发问题,直到您在其中使用共享变量为止,换句话说, “无状态对象始终是线程安全的”。

Servlet is quite good example of it ;) Servlet是一个很好的例子;)

edited. 编辑。

For making your code safe I recommend you to do follow: 为了使您的代码安全,我建议您执行以下操作:

private static Connection connect() throws Exception {
  if (ds == null) {
    synchronized (Connection.class) {
      if (ds == null) {
        getDataSource();
      }
    }
  }
  return ds.getConnection();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM