Servlet日記(1999/11/14)

本日の成果

 昨日の続きで、コネクションプールを作ってみました。なんだか大げさな処理になっていますが、要するに最初にConnectionオブジェクトを作ってデータベースに接続しておき、あとはそれを使い回すだけです。

 一応コネクションプールとしては動作しているようです。が、ここまで考えると、今度はトランザクション間の関係が気になってくるわけで、Servletからは離れていくので、これでおしまい。

class ConnectionPool {
  class ConnectionPoolElement {
    Connection con;
    boolean used;
  }

  static final int INIT_NUM_CONNECTION = 10;
  static final int ADD_NUM_CONNECTION = 5;
  Vector pool;
  String url, user, pwd;

  ConnectionPool(String url, String user, String pwd) throws SQLException {
    pool = new Vector();
    this.url = url;
    this.user = user;
    this.pwd = pwd;
    createConnectionPool(INIT_NUM_CONNECTION);
  }

  private void createConnectionPool(int numConnection) throws SQLException {
    ConnectionPoolElement elm;

    for (int i = 0; i < numConnection; i++) {
      elm = new ConnectionPoolElement();
      elm.con = DriverManager.getConnection(this.url, this.user, this.pwd);
      elm.used = false;
      pool.addElement(elm);
    }
  }

  synchronized void destroyConnection() throws SQLException {
    ConnectionPoolElement elm;

    for (int i = 0; i < pool.size(); i++) {
      elm = (ConnectionPoolElement)(pool.elementAt(i));
      elm.con.close();
    }
  }

  synchronized Connection getConnection() throws SQLException, Exception {
    ConnectionPoolElement elm;

    for (;;) {
      for (int i = 0; i < pool.size(); i++) {
        elm = (ConnectionPoolElement)(pool.elementAt(i));
        if (! elm.used) {
          System.out.println("getConnection: i=" + i);
          elm.used = true;
          return elm.con;
        }
      }

      createConnectionPool(ADD_NUM_CONNECTION);
    }
  }

  synchronized void releaseConnection(Connection con) throws Exception {
    ConnectionPoolElement elm;

    for (int i = 0; i < pool.size(); i++) {
      elm = (ConnectionPoolElement)(pool.elementAt(i));
      if (elm.con == con) {
        System.out.println("releaseConnection: i=" + i);
        elm.used = false;
        return;
      }
    }

    throw new Exception("unknown Connection");
  }
}

public class Servlet1 extends HttpServlet {
  ConnectionPool cp = null;

  public void init(ServletConfig config) throws ServletException {
    super.init(config);

    try {
      Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
      cp = new ConnectionPool("jdbc:odbc:shain", "admin", "admin");
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public void destroy() {
    try {
      cp.destroyConnection();
    } catch (Exception e) {
      e.printStackTrace();
    }

    super.destroy();
  }

  public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    Connection con = null;

    try {
      con = cp.getConnection();
      このあたりは昨日と同じ
    } finally {
      try {
        cp.releaseConnection(con);
      } catch (Exception e) {
      }
    }
  }

  public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    Connection con = null;
    このあたりは昨日と同じ

    try {
      con = cp.getConnection();
      このあたりは昨日と同じ

    } finally {
      try {
        stmt.close();
        con.setAutoCommit(true);
        cp.releaseConnection(con);
      } catch (Exception e2) {
      }
    }

    doGet(request, response);
  }

本日の教訓

 コネクションプールを作ってみました。かろうじて動いているようですが、全然実用的ではありません。こういうものは片手間にちょろっと作るものではありませんよね。

Servlet日記(1999/11/13) Servlet日記の目次 Servlet日記(1999/11/21)