Java 链接池的工做原理

什么是链接?java

链接,是咱们的编程语言与数据库交互的一种方式。咱们常常会听到这么一句话“数据库链接很昂贵“。mysql

有人接受这种说法,殊不知道它的真正含义。所以,下面我将解释它到底是什么。[若是你已经知道了,你能够跳到它的工做原理部分]sql

建立链接的代码片断:数据库

?编程

1数组

2dom

3编程语言

String connUrl = "jdbc:mysql://your.database.domain/yourDBname"; ide

Class.forName("com.mysql.jdbc.Driver"); url

Connection con = DriverManager.getConnection (connUrl);

 

当咱们建立了一个Connection对象,它在内部都执行了什么:

1.“DriverManager”检查并注册驱动程序,
2.“com.mysql.jdbc.Driver”就是咱们注册了的驱动程序,它会在驱动程序类中调用“connect(url…)”方法。
3.com.mysql.jdbc.Driver的connect方法根据咱们请求的“connUrl”,建立一个“Socket链接”,链接到IP为“your.database.domain”,默认端口3306的数据库。
4.建立的Socket链接将被用来查询咱们指定的数据库,并最终让程序返回获得一个结果。

为何昂贵?

如今让咱们谈谈为何说它“昂贵“。

若是建立Socket链接花费的时间比实际的执行查询的操做所花费的时间还要更长。

这就是咱们所说的“数据库链接很昂贵”,由于链接资源数是1,它须要每次建立一个Socket链接来访问DB。

所以,咱们将使用链接池。

链接池初始化时建立必定数量的链接,而后从链接池中重用链接,而不是每次建立一个新的。

怎样工做?

接下来咱们来看看它是如何工做,以及如何管理或重用现有的链接。

咱们使用的链接池供应者,它的内部有一个链接池管理器,当它被初始化:

1.它建立链接池的默认大小,好比指定建立5个链接对象,并把它存放在“可用”状态的任何集合或数组中。

例如,代码片断:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

...

  String connUrl = "jdbc:mysql://your.database.domain/yourDBname";

  String driver = "com.mysql.jdbc.Driver";

  private Map<java.sql.Connection, String> connectionPool = null;

  private void initPool() {

    try {

      connectionPool = new HashMap<java.sql.Connection, String>();

      Class.forName(driver);

      java.sql.Connection con = DriverManager.getConnection(dbUrl);

      for (int poolInd = poolSize; poolInd < 0; poolInd++) {

        connectionPool.put(con, "AVAILABLE");

      }

  }

...

 

2.当咱们调用connectionProvider.getConnection(),而后它会从集合中获取一个链接,固然状态也会更改成“不可用”。

例如,代码片断:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

...

  public java.sql.Connection getConnection() throws ClassNotFoundException, SQLException

  {

      boolean isConnectionAvailable = true;

      for (Entry<java.sql.Connection, String> entry : connectionPool.entrySet()) {

          synchronized (entry) {

              if (entry.getValue()=="AVAILABLE") {

                  entry.setValue("NOTAVAILABLE");

                  return (java.sql.Connection) entry.getKey();

              }

              isConnectionAvailable = false;

          }

      }

      if (!isConnectionAvailable) {

          Class.forName(driver);

          java.sql.Connection con = DriverManager.getConnection(connUrl);

          connectionPool.put(con, "NOTAVAILABLE");

          return con;

      }

      return null;

  }

  ...

3.当咱们关闭获得的链接,ConnectionProvider是不会真正关闭链接。相反,只是将状态更改成“AVAILABLE”。

例如,代码片断:

?

1

2

3

4

5

6

7

8

9

10

11

12

...

public void closeConnection(java.sql.Connection connection) throws ClassNotFoundException, SQLException {

    for (Entry<java.sql.Connection, String> entry : connectionPool.entrySet()) {

        synchronized (entry) {

            if (entry.getKey().equals(connection)) {

                //Getting Back the conncetion to Pool

                entry.setValue("AVAILABLE");

            }

        }

    }

}

...

 

基本上链接池的实际工做原理就是这样,但也有可能使用不一样的方式。

如今,你可能有一个问题,咱们是否能够创造咱们本身的链接池机制?
 
个人建议是使用已经存在的链接池机制,像C3P0DBCP等。

相关文章
相关标签/搜索