Link Pool Detailed

Source: Internet
Author: User
Tags date odbc stmt version variable thread time limit valid
Detailed to the current target, the JDBC2 of the connection pool is just an interface, there is no real implementation, JDBC3 is being developed,
The link pool is reported to have been supported, but ...
JDBC3 with the Jndi technology, the connection pool configuration can let a master all annoying death.

At present, the third party has already implemented the connection pool is of course the poolman,1.0 version for the general user is enough to use. Configuration is also simple, although the 2.0 version added some features, but the configuration is also using Jndi, the RMI and EJB do not understand friends may be annoying. It is recommended to use 1.0 of the.

If you are interested, you can also implement the connection pool, the most critical technology is to pass the link as a parameter to a bean, used to return this parameter link instead of closing.
Here's a simple implementation:
The list of Dbconnectionmanager.java procedures is as follows:

001 Import java.io.*;
002 Import java.sql.*;
003 Import java.util.*;
004 Import Java.util.Date;
005
006/**
007 * Management class Dbconnectionmanager support for one or more database connections defined by a property file
008 * Pool Access. The client program can call the GetInstance () method to access the unique instance of this class.
009 */
010 public class Dbconnectionmanager {
011 static private Dbconnectionmanager instance; Unique instance
012 static private int clients;
013
014 Private Vector drivers = new vector ();
015 private PrintWriter log;
016 Private Hashtable pools = new Hashtable ();
017
018/**
019 * Returns a unique instance. If this is the first time this method is called, the instance is created
020 *
021 * @return Dbconnectionmanager Unique instance
022 */
023 static synchronized public Dbconnectionmanager getinstance () {
024 if (instance = = null) {
025 instance = new Dbconnectionmanager ();
026}
027 clients++;
028 return instance;
029}
030
031/**
032 * Constructor Private to prevent other objects from creating instances of this class
033 */
034 Private Dbconnectionmanager () {
035 Init ();
036}
037
038/**
039 * Return the Connection object to the connection pool specified by name
040 *
041 * @param name of the connection pool defined in the property file
042 * @param con connection object \ r
043 */
044 public void Freeconnection (String name, Connection con) {
045 Dbconnectionpool pool = (dbconnectionpool) pools.get (name);
046 if (pool!= null) {
047 pool.freeconnection (con);
048}
049}
050
051/**
052 * Get an available (free) connection. If no connection is available and the number of connections is less than the maximum number of connections
053 * limit, create and return new connection
054 *
055 * @param name of the connection pool defined in the property file
056 * @return Connection available connection or null
057 */
058 public Connection getconnection (String name) {
059 Dbconnectionpool pool = (dbconnectionpool) pools.get (name);
060 if (pool!= null) {
061 return pool.getconnection ();
062}
063 return null;
064}
065
066/**
067 * Obtain an available connection. If no connection is available and the number of connections is less than the maximum number of connections,
068 * Creates and returns a new connection. Otherwise, wait for the other thread to release the connection within the specified time.
069 *
070 * @param name Connection pool name
071 * @param time wait in milliseconds \ r
072 * @return Connection available connection or null
073 */
074 public Connection getconnection (String name, long time) {
075 Dbconnectionpool pool = (dbconnectionpool) pools.get (name);
076 if (pool!= null) {
077 return Pool.getconnection (time);
078}
079 return null;
080}
081
082/**
083 * Close all connections, revoke driver registration \ r
084 */
085 public synchronized void release () {
086/Wait until the last client calls
087 if (--clients!= 0) {
088 return;
089}
090
091 Enumeration allpools = Pools.elements ();
092 while (allpools.hasmoreelements ()) {
093 Dbconnectionpool pool = (dbconnectionpool) allpools.nextelement ();
094 pool.release ();
095}
096 Enumeration alldrivers = Drivers.elements ();
097 while (alldrivers.hasmoreelements ()) {
098 Driver Driver = (Driver) alldrivers.nextelement ();
099 try {
Drivermanager.deregisterdriver (driver);
Log ("Undo JDBC Driver" + driver.getclass (). GetName () + "registration \");
102}
The catch (SQLException e) {
Log (E, "cannot undo the registration of the following JDBC driver:" + driver.getclass (). GetName ());
105}
106}
107}
108
109/**
110 * Create a connection pool instance based on the specified properties.
111 *
112 * @param props Connection Pool Properties
113 */
114 private void Createpools (Properties props) {
Enumeration propnames = Props.propertynames ();
116 while (propnames.hasmoreelements ()) {
117 String name = (string) propnames.nextelement ();
118 if (Name.endswith (". url")) {
119 String poolname = name.substring (0, Name.lastindexof ("."));
The String url = props.getproperty (poolname + ". url");
121 if (url = = null) {
122 log ("No connection pool" + poolname + "Specify URL");
123 continue;
124}
The props.getproperty String user = poolname + ". User");
126 String Password = props.getproperty (poolname + ". Password");
127 String Maxconn = props.getproperty (poolname + ". Maxconn", "0");
128 int Max;
129 try {
130 max = integer.valueof (maxconn). Intvalue ();
131}
132 catch (NumberFormatException e) {
The maximum number of connections: "+ Maxconn +". Connection pool: "+ poolname";
134 max = 0;
135}
136 Dbconnectionpool Pool =
137 New Dbconnectionpool (poolname, url, user, password, max);
138 Pools.put (poolname, pool);
139 Log ("Successfully create connection pool" + poolname);
140}
141}
142}
143
144/**
145 * Read Property complete initialization
146 */
147 private void init () {
148 InputStream is = GetClass (). getResourceAsStream ("/db.properties");
149 Properties Dbprops = new properties ();
The try {
151 Dbprops.load (IS);
152}
153 catch (Exception e) {
154 System.err.println ("Cannot read property file." +
155 "Please make sure db.properties is in the path specified by Classpath");
156 return;
157}
158 String LogFile = Dbprops.getproperty ("LogFile", "DBConnectionManager.log");
159 try {
160 log = new PrintWriter (new FileWriter (LogFile, True), true);
161}
162 catch (IOException e) {
163 System.err.println ("Unable to open log file:" + logFile);
164 log = new PrintWriter (SYSTEM.ERR);
165}
166 Loaddrivers (Dbprops);
167 Createpools (Dbprops);
168}
169
170/**
171 * Loading and registering all JDBC drivers \ r
172 *
173 * @param Props Properties
174 */
175 private void Loaddrivers (Properties props) {
176 String driverclasses = Props.getproperty ("Drivers");
177 StringTokenizer st = new StringTokenizer (driverclasses);
178 while (st.hasmoreelements ()) {
179 String driverclassname = St.nexttoken (). Trim ();
180 try {
181 Driver Driver = (Driver)
Class.forName (Driverclassname). newinstance ();
183 Drivermanager.registerdriver (driver);
184 drivers.addelement (driver);
185 log ("successfully registers JDBC driver \" + driverclassname);
186}
187 catch (Exception e) {
188 log ("Unable to register JDBC driver:" +
189 Driverclassname + ", Error:" + E);
190}
191}
192}
193
194/**
195 * Write text information to the log file
196 */
197 private void log (String msg) {
198 log.println (New Date () + ":" + msg);
199}
200
201/**
202 * Write text information and exceptions to the log file
203 */
204 private void Log (Throwable e, String msg) {
205 Log.println (New Date () + ":" + msg);
206 E.printstacktrace (log);
207}
208
209/**
210 * This inner class defines a connection pool. It is able to create new connections as required until the most scheduled \ r
211 * Large connection number. It can verify the validity of the connection before returning to the client program.
212 */
213 class Dbconnectionpool {
214 private int checkedout;
215 private vector freeconnections = new vector ();
216 private int maxconn;
217 private String name;
218 private String password;
219 Private String URL;
a private String user;
221
222/**
223 * Create a new connection pool
224 *
@param name Connection pool name
The JDBC URL for @param URL database
@param user Database account number, or null
228 * @param password password, or null
229 * @param maxconn The maximum number of connections allowed for this connection pool
230 */
231 public Dbconnectionpool (string name, string URL, string user, string password,
232 int maxconn) {
233 this.name = name;
234 this. url = URL;
235 This.user = user;
236 This.password = password;
237 This.maxconn = Maxconn;
238}
239
240/**
241 * Return the connection to the connection pool that is no longer in use
242 *
243 * @param con Client release connection
244 */
245 public synchronized void freeconnection (Connection con) {
246//Add the specified connection to the end of the vector
247 freeconnections.addelement (con);
248 checkedout--;
249 Notifyall ();
250}
251
252/**
253 * Obtain an available connection from the connection pool. If there is no free connection and the current number of connections is less than the maximum connection
254 * Number limit, a new connection is created. If the previously registered connection is no longer valid, remove it from the vector,
255 * Then recursively calls itself to try the new available connection.
256 */
257 Public synchronized Connection getconnection () {
258 Connection con = null;
259 if (freeconnections.size () > 0) {
260//Get the first available connection in the vector
261 con = (Connection) freeconnections.firstelement ();
262 Freeconnections.removeelementat (0);
263 try {
264 if (con.isclosed ()) {
265 log ("Remove an invalid connection from the connection pool" + name+);
266//Recursive call yourself, try to get the available connection again
267 con = getconnection ();
268}
269}
270 catch (SQLException e) {
271 log ("Remove an invalid connection from the connection pool" + name+);
272//Recursive call yourself, try to get the available connection again
273 con = getconnection ();
274}
275}
276 else if (maxconn = 0 | | Checkedout < maxconn) {
277 con = newconnection ();
278}
279 if (con!= null) {
280 checkedout++;
281}
282 return con;
283}
284
285/**
286 * Get the available connections from the connection pool. You can specify the maximum time that a client can wait. \ r
287 * See previous getconnection () method.
288 *
289 * @param timeout wait time limit in milliseconds
290 */
291 Public synchronized Connection getconnection (long timeout) {
292 Long starttime = new Date (). GetTime ();
293 Connection con;
294 while (con = getconnection () = = null) {
295 try {
296 wait (timeout);
297}
298 catch (Interruptedexception e) {}
299 if (new Date (). GetTime ()-starttime) >= timeout) {
The reason for the return of A//wait () is a timeout
The rule return null;
302}
303}
304 return con;
305}
306
307/**
308 * Close all connections
309 */
310 Public synchronized void release () {
311 Enumeration allconnections = Freeconnections.elements ();
312 while (Allconnections.hasmoreelements ()) {
313 Connection con = (Connection) allconnections.nextelement ();
The A-a-try {
315 Con.close ();
316 log ("Close connection pool" + name+ "one Connection");
317}
318 catch (SQLException e) {
319 log (E, "Connection in connection pool" + name+ ");
320}
321}
322 freeconnections.removeallelements ();
323}
324
325/**
326 * Create a new connection
327 */
328 private Connection newconnection () {
329 Connection con = null;
The # try {
331 if (user = null) {
332 con = drivermanager.getconnection (URL);
333}
334 else {
335 con = drivermanager.getconnection (URL, user, password);
336}
337 log ("Connection pool" + name+ "create a new Connection");
338}
339 catch (SQLException e) {
Log (E, "cannot create a connection to the following URL:" + URL);
341 return null;
342}
343 return con;
344}
345}
346}


Iii. class Dbconnectionpool description \ R

This class is implemented in rows 209 through 345, which represents a connection pool that points to a database. The database is identified by the JDBC URL. A JDBC URL consists of three parts: the protocol identifier (always JDBC), the driver identification (such as ODBC, IDB, Oracle, and so on), and the database identity (its format is dependent on the driver). For example, Jdbc:odbc:demo is a JDBC URL that points to the demo database, and access to the database uses the JDBC-ODBC driver. Each connection pool has a name for use by the client program and an optional user account, password, maximum number of connections. If some of the database operations supported by a Web application can be performed by all users, while others should be performed by a specially licensed user, a connection pool can be defined for two types of operations, two connection pools use the same JDBC URL, but different accounts and passwords are used.
The constructor for class Dbconnectionpool requires all of the above data as its parameters. As shown in lines 222 through 238, the data is saved as its instance variable:
As shown in rows 252 through 283, 285 to 305, the client program can use the two methods provided by the Dbconnectionpool class to obtain the available connections. The common point is that if there is an available connection in the connection pool, it is returned directly, otherwise a new connection is created and returned. If no connection is available and the total number of connected connections equals the maximum limit, the first method returns null directly, and the second method waits until there is an available connection.
All available connection objects are registered in vectors named freeconnections (vector). If there are more than one connection in the vector, getconnection () always selects the first one. At the same time, because new, available connections always add vectors from the tail, the risk of a database connection being shut down for long periods of time is minimized.
The first getconnection () called the IsClosed () method to verify that the connection is still valid before returning the available connection to the client. If the connection is closed or an exception is triggered, getconnection () recursively calls itself to try to get another available connection. If there are no available connections in the vector freeconnections, the getconnection () method checks to see if the maximum number of connections has been specified. If specified, checks to see if the current number of connections has reached the limit. Here Maxconn 0 means there is no limit. If you do not specify the maximum number of connections or the current number of connections is less than this value, the method attempts to create a new connection. If the creation succeeds, the count of the used connection is incremented and returned, otherwise null is returned.
As shown in lines 325 through 345, creating a new connection is implemented by the Newconnection () method. The creation process is related to whether the database account number or password has been specified.
The DriverManager class of JDBC provides multiple getconnection () methods that use JDBC URLs and other parameters, such as user accounts and passwords. DriverManager will use the specified JDBC URL to determine the driver that is appropriate for the target database and establish the connection.
The second getconnection () method implemented in lines 285 through 305 requires a time parameter in milliseconds, which represents the maximum time that a client program can wait. The exact operation of establishing a connection is still implemented by the first getconnection () method.
When the method executes, the StartTime is initialized to the current time. Try to get a connection in the while loop. If it fails, the wait () is invoked with the given time value as the parameter. The return of Wait () may be due to another thread calling notify () or Notifyall (), or possibly due to a scheduled time. To find the real reason for the return of Wait (), the program uses the current time minus start (starttime), and returns null if the difference is greater than the scheduled time, otherwise the getconnection () is called again.
Registering an idle connection into the connection pool is implemented by the Freeconnection () method of 240 to 250 rows, and its parameters are the connection objects returned to the connection pool. The object is added to the end of the freeconnections vector, and then the connection count is reduced. The call to Notifyall () is to notify other threads that are waiting for an available connection.
Many servlet engines provide several ways to implement secure shutdown. The database connection pool needs to know about the event to ensure that all connections are shut down properly. The Dbconnectionmanager class negatively coordinates the entire shutdown process, but the task of shutting down all connections in the connection pool is owned by the Dbconnectionpool class. The release () method implemented in lines 307 through 323 is for Dbconnectionmanager calls. The method traverses the freeconnections vector and closes all the connections, and then removes them from the vector.


Iv. class Dbconnectionmanager description \ R

The class can only create one instance, and other objects can call its static method (also called a class method) to obtain a reference to that unique instance. As shown in lines 031 through 036, the constructors for the Dbconnectionmanager class are private, in order to prevent other objects from creating instances of the class.
The client program for the Dbconnectionmanager class can call the GetInstance () method to obtain a reference to the unique instance of the class. As shown in rows 018 through 029, a unique instance of a class is created during the first invocation of the getinstance () method, and its reference is then persisted in the static variable instance. Each call to getinstance () adds a dbconnectionmanager count of the client program. That is, the count represents the total number of client programs referencing the Dbconnectionmanager unique instance, which will be used to control the shutdown operation of the connection pool.
The initialization of the class instance is done by the private Method init () between 146 and 168 rows. where the getResourceAsStream () method is used to locate and open an external file. The location method of an external file relies on the implementation of the class loader. The standard local class loader lookup operation always starts at the path where the class file resides, and can also search for the path declared in Classpath. Db.properties is a property file that contains key-value pairs that define the connection pool. The common properties that are available for definition are as follows:

Drivers a space-delimited list of JDBC driver classes \ r
LogFile the absolute path of the log file

Other properties are associated with a specific connection pool, and the name of the connection pool should precede the attribute names:

< JDBC URL for poolname>.url database
< Poolname>.maxconn maximum number of connections allowed to be established, 0 means no Limit
< Poolname>.user Database account number for this connection pool
< poolname>.password the corresponding password \ r

Where the URL property is required, and the other properties are optional. The database account number and password must be legal. Examples of db.properties files for the Windows platform are as follows:

Drivers=sun.jdbc.odbc.jdbcodbcdriver Jdbc.idbdriver
Logfile=d:\\user\\src\\java\\dbconnectionmanager\\log.txt

Idb.url=jdbc:idb:c:\\local\\javawebserver1.1\\db\\db.prp
idb.maxconn=2

Access.url=jdbc:odbc:demo
Access.user=demo
Access.password=demopw

Note that the backslash in the Windows path must be entered in 2, because the backslash in the property file is also an escape character.
After creating the Property object and reading the Db.properties file, the init () method begins checking the LogFile property. If the log file is not specified in the property file, the DBConnectionManager.log file in the current directory is assumed to be the default. If the log file is not available, output logging to System.err.
Mounts and registers all the JDBC drivers specified in the drivers property, implemented by the Loaddrivers () method between 170 and 192 rows. The method first splits the drivers property value into a string corresponding to the driver name, then loads the classes and then stringtokenizer the example, and finally registers the instance in DriverManager and adds it to a private vector drivers. The vector drivers will be used to cancel the registration of all JDBC drivers from DriverManager when the service is closed.
The last task of the Init () method is to invoke the private method Createpools () to create the connection pool object. As shown in lines 109 through 142, the Createpools () method first creates an enumeration object (that is, the enumeration object, which can be imagined as a series of elements and called its nextelement () method to return the elements sequentially) to all the property names. It then searches for a property whose name ends with ". url". For each eligible attribute, the first part of the connection pool name is extracted, which reads all the attributes that belong to the connection pool, and finally creates the connection pool object and saves it in the instance variable pools. The hash table (Hashtable class) pools implements a mapping between the connection pool name and the connection pool object, where the connection pool name is the key and the connection pool object is a value.
Class Dbconnectionmanager provides methods getconnection () and freeconnection () to facilitate the client to obtain an available connection from the specified connection pool or to return the connection to the connection pool. All of these methods require a connection pool name to be specified in the parameter, and a specific connection fetch or return operation calls the corresponding connection pool object to complete. Their implementations are from 051 to 064 rows, 066 to 080 rows, and 038 to 049 rows respectively.
As shown in lines 082 through 107, Dbconnectionmanager provides method release () for the safe shutdown of the connection pool. As we have mentioned above, all Dbconnectionmanager clients should call the static method getinstance () to obtain a reference to the manager, which will increase the client count. The client program calls release () at shutdown to decrement the count. When the last client invokes release () and the decremented reference count is 0, you can call the release () method of each connection pool to close all connections. The final task of the Management class release () method is to revoke the registration of all JDBC drivers.


V. servlet use connection pooling example

The servlet lifecycle classes defined by the Servlet API are as follows:

1 Create and initialize the servlet (init () method).
2 Respond to Client service requests (services () method).
3 The servlet terminates the operation, releasing all Resources (Destroy () method).

This example demonstrates the connection pool application, and the relevant actions in the above key steps are:

1 in init (), use the instance variable connmgr to save the reference returned by the call Dbconnectionmanager.getinstance ().
2 in service (), call getconnection (), perform database operations, and return the connection to the connection pool with freeconnection ().
3 in Destroy (), call Release () to close all connections, releasing all resources.

The list of sample programs is as follows:

Import java.io.*;
Import java.sql.*;
Import javax.servlet.*;
Import javax.servlet.http.*;
public class Testservlet extends HttpServlet {
Private Dbconnectionmanager connmgr;

public void init (ServletConfig conf) throws Servletexception {
Super.init (conf);
Connmgr = Dbconnectionmanager.getinstance ();
}

public void Service (HttpServletRequest req, httpservletresponse Res)
Throws IOException {

Res.setcontenttype ("text/html");
PrintWriter out = Res.getwriter ();
Connection con = connmgr.getconnection ("IDB");
if (con = = null) {
OUT.PRINTLN ("Cannot get database connection.");
Return
}
ResultSet rs = null;
ResultSetMetaData MD = NULL;
Statement stmt = null;
try {
stmt = Con.createstatement ();
rs = Stmt.executequery ("SELECT * from EMPLOYEE");
md = Rs.getmetadata ();
Out.println ("< h1> employee Data while (Rs.next ()) {
Out.println ("< br>");
for (int i = 1; i < Md.getcolumncount (); i++) {
Out.print (rs.getstring (i) + ",");
}
}
Stmt.close ();
Rs.close ();
}
catch (SQLException e) {
E.printstacktrace (out);
}
Connmgr.freeconnection ("IDB", con);
}

public void Destroy () {
Connmgr.release ();
Super.destroy ();
}
}


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.