Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/apache/commons/dbcp/PoolableConnectionFactory.java


1   /*
2    * Copyright 1999-2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.apache.commons.dbcp;
18  
19  import java.sql.Connection;
20  import java.sql.Statement;
21  import java.sql.ResultSet;
22  import java.sql.SQLException;
23  import org.apache.commons.pool.*;
24  
25  /**
26   * A {@link PoolableObjectFactory} that creates
27   * {@link PoolableConnection}s.
28   *
29   * @author Rodney Waldhoff
30   * @author Glenn L. Nielsen
31   * @author James House
32   * @author Dirk Verbeeck
33   * @version $Revision: 1.23 $ $Date: 2004/06/09 18:21:23 $
34   */
35  public class PoolableConnectionFactory implements PoolableObjectFactory {
36      /**
37       * Create a new <tt>PoolableConnectionFactory</tt>.
38       * @param connFactory the {@link ConnectionFactory} from which to obtain base {@link Connection}s
39       * @param pool the {@link ObjectPool} in which to pool those {@link Connection}s
40       * @param stmtPoolFactory the {@link KeyedObjectPoolFactory} to use to create {@link KeyedObjectPool}s for pooling {@link java.sql.PreparedStatement}s, or <tt>null</tt> to disable {@link java.sql.PreparedStatement} pooling
41       * @param validationQuery a query to use to {@link #validateObject validate} {@link Connection}s.  Should return at least one row. Using <tt>null</tt> turns off validation.
42       * @param defaultReadOnly the default "read only" setting for borrowed {@link Connection}s
43       * @param defaultAutoCommit the default "auto commit" setting for returned {@link Connection}s
44       */
45      public PoolableConnectionFactory(ConnectionFactory connFactory, ObjectPool pool, KeyedObjectPoolFactory stmtPoolFactory, String validationQuery, boolean defaultReadOnly, boolean defaultAutoCommit) {
46          _connFactory = connFactory;
47          _pool = pool;
48          _pool.setFactory(this);
49          _stmtPoolFactory = stmtPoolFactory;
50          _validationQuery = validationQuery;
51          _defaultReadOnly = defaultReadOnly ? Boolean.TRUE : Boolean.FALSE;
52          _defaultAutoCommit = defaultAutoCommit;
53      }
54  
55      /**
56       * Create a new <tt>PoolableConnectionFactory</tt>.
57       * @param connFactory the {@link ConnectionFactory} from which to obtain base {@link Connection}s
58       * @param pool the {@link ObjectPool} in which to pool those {@link Connection}s
59       * @param stmtPoolFactory the {@link KeyedObjectPoolFactory} to use to create {@link KeyedObjectPool}s for pooling {@link java.sql.PreparedStatement}s, or <tt>null</tt> to disable {@link java.sql.PreparedStatement} pooling
60       * @param validationQuery a query to use to {@link #validateObject validate} {@link Connection}s.  Should return at least one row. Using <tt>null</tt> turns off validation.
61       * @param defaultReadOnly the default "read only" setting for borrowed {@link Connection}s
62       * @param defaultAutoCommit the default "auto commit" setting for returned {@link Connection}s
63       * @param defaultTransactionIsolation the default "Transaction Isolation" setting for returned {@link Connection}s
64       */
65      public PoolableConnectionFactory(ConnectionFactory connFactory, ObjectPool pool, KeyedObjectPoolFactory stmtPoolFactory, String validationQuery, boolean defaultReadOnly, boolean defaultAutoCommit, int defaultTransactionIsolation) {
66          _connFactory = connFactory;
67          _pool = pool;
68          _pool.setFactory(this);
69          _stmtPoolFactory = stmtPoolFactory;
70          _validationQuery = validationQuery;
71          _defaultReadOnly = defaultReadOnly ? Boolean.TRUE : Boolean.FALSE;
72          _defaultAutoCommit = defaultAutoCommit;
73          _defaultTransactionIsolation = defaultTransactionIsolation;
74      }
75  
76      /**
77       * Create a new <tt>PoolableConnectionFactory</tt>.
78       * @param connFactory the {@link ConnectionFactory} from which to obtain base {@link Connection}s
79       * @param pool the {@link ObjectPool} in which to pool those {@link Connection}s
80       * @param stmtPoolFactory the {@link KeyedObjectPoolFactory} to use to create {@link KeyedObjectPool}s for pooling {@link java.sql.PreparedStatement}s, or <tt>null</tt> to disable {@link java.sql.PreparedStatement} pooling
81       * @param validationQuery a query to use to {@link #validateObject validate} {@link Connection}s.  Should return at least one row. Using <tt>null</tt> turns off validation.
82       * @param defaultReadOnly the default "read only" setting for borrowed {@link Connection}s
83       * @param defaultAutoCommit the default "auto commit" setting for returned {@link Connection}s
84       * @param config the AbandonedConfig if tracing SQL objects
85       * @deprecated AbandonedConfig is now deprecated.
86       */
87      public PoolableConnectionFactory(
88          ConnectionFactory connFactory,
89          ObjectPool pool,
90          KeyedObjectPoolFactory stmtPoolFactory,
91          String validationQuery,
92          boolean defaultReadOnly,
93          boolean defaultAutoCommit,
94          AbandonedConfig config) {
95              
96          _connFactory = connFactory;
97          _pool = pool;
98          _config = config;
99          _pool.setFactory(this);
100         _stmtPoolFactory = stmtPoolFactory;
101         _validationQuery = validationQuery;
102         _defaultReadOnly = defaultReadOnly ? Boolean.TRUE : Boolean.FALSE;
103         _defaultAutoCommit = defaultAutoCommit;
104     }
105 
106     /**
107      * Create a new <tt>PoolableConnectionFactory</tt>.
108      * @param connFactory the {@link ConnectionFactory} from which to obtain base {@link Connection}s
109      * @param pool the {@link ObjectPool} in which to pool those {@link Connection}s
110      * @param stmtPoolFactory the {@link KeyedObjectPoolFactory} to use to create {@link KeyedObjectPool}s for pooling {@link java.sql.PreparedStatement}s, or <tt>null</tt> to disable {@link java.sql.PreparedStatement} pooling
111      * @param validationQuery a query to use to {@link #validateObject validate} {@link Connection}s.  Should return at least one row. Using <tt>null</tt> turns off validation.
112      * @param defaultReadOnly the default "read only" setting for borrowed {@link Connection}s
113      * @param defaultAutoCommit the default "auto commit" setting for returned {@link Connection}s
114      * @param defaultTransactionIsolation the default "Transaction Isolation" setting for returned {@link Connection}s
115      * @param config the AbandonedConfig if tracing SQL objects
116      * @deprecated AbandonedConfig is now deprecated.
117      */
118     public PoolableConnectionFactory(
119         ConnectionFactory connFactory,
120         ObjectPool pool,
121         KeyedObjectPoolFactory stmtPoolFactory,
122         String validationQuery,
123         boolean defaultReadOnly,
124         boolean defaultAutoCommit,
125         int defaultTransactionIsolation,
126         AbandonedConfig config) {
127             
128         _connFactory = connFactory;
129         _pool = pool;
130         _config = config;
131         _pool.setFactory(this);
132         _stmtPoolFactory = stmtPoolFactory;
133         _validationQuery = validationQuery;
134         _defaultReadOnly = defaultReadOnly ? Boolean.TRUE : Boolean.FALSE;
135         _defaultAutoCommit = defaultAutoCommit;
136         _defaultTransactionIsolation = defaultTransactionIsolation;
137     }
138 
139     /**
140      * Create a new <tt>PoolableConnectionFactory</tt>.
141      * @param connFactory the {@link ConnectionFactory} from which to obtain base {@link Connection}s
142      * @param pool the {@link ObjectPool} in which to pool those {@link Connection}s
143      * @param stmtPoolFactory the {@link KeyedObjectPoolFactory} to use to create {@link KeyedObjectPool}s for pooling {@link java.sql.PreparedStatement}s, or <tt>null</tt> to disable {@link java.sql.PreparedStatement} pooling
144      * @param validationQuery a query to use to {@link #validateObject validate} {@link Connection}s.  Should return at least one row. Using <tt>null</tt> turns off validation.
145      * @param defaultReadOnly the default "read only" setting for borrowed {@link Connection}s
146      * @param defaultAutoCommit the default "auto commit" setting for returned {@link Connection}s
147      * @param defaultTransactionIsolation the default "Transaction Isolation" setting for returned {@link Connection}s
148      * @param defaultCatalog the default "catalog" setting for returned {@link Connection}s
149      * @param config the AbandonedConfig if tracing SQL objects
150      * @deprecated AbandonedConfig is now deprecated.
151      */
152     public PoolableConnectionFactory(
153         ConnectionFactory connFactory,
154         ObjectPool pool,
155         KeyedObjectPoolFactory stmtPoolFactory,
156         String validationQuery,
157         boolean defaultReadOnly,
158         boolean defaultAutoCommit,
159         int defaultTransactionIsolation,
160         String defaultCatalog,
161         AbandonedConfig config) {
162             
163         _connFactory = connFactory;
164         _pool = pool;
165         _config = config;
166         _pool.setFactory(this);
167         _stmtPoolFactory = stmtPoolFactory;
168         _validationQuery = validationQuery;
169         _defaultReadOnly = defaultReadOnly ? Boolean.TRUE : Boolean.FALSE;
170         _defaultAutoCommit = defaultAutoCommit;
171         _defaultTransactionIsolation = defaultTransactionIsolation;
172         _defaultCatalog = defaultCatalog;
173     }
174 
175     /**
176      * Create a new <tt>PoolableConnectionFactory</tt>.
177      * @param connFactory the {@link ConnectionFactory} from which to obtain base {@link Connection}s
178      * @param pool the {@link ObjectPool} in which to pool those {@link Connection}s
179      * @param stmtPoolFactory the {@link KeyedObjectPoolFactory} to use to create {@link KeyedObjectPool}s for pooling {@link java.sql.PreparedStatement}s, or <tt>null</tt> to disable {@link java.sql.PreparedStatement} pooling
180      * @param validationQuery a query to use to {@link #validateObject validate} {@link Connection}s.  Should return at least one row. Using <tt>null</tt> turns off validation.
181      * @param defaultReadOnly the default "read only" setting for borrowed {@link Connection}s
182      * @param defaultAutoCommit the default "auto commit" setting for returned {@link Connection}s
183      * @param defaultTransactionIsolation the default "Transaction Isolation" setting for returned {@link Connection}s
184      * @param defaultCatalog the default "catalog" setting for returned {@link Connection}s
185      * @param config the AbandonedConfig if tracing SQL objects
186      */
187     public PoolableConnectionFactory(
188         ConnectionFactory connFactory,
189         ObjectPool pool,
190         KeyedObjectPoolFactory stmtPoolFactory,
191         String validationQuery,
192         Boolean defaultReadOnly,
193         boolean defaultAutoCommit,
194         int defaultTransactionIsolation,
195         String defaultCatalog,
196         AbandonedConfig config) {
197             
198         _connFactory = connFactory;
199         _pool = pool;
200         _config = config;
201         _pool.setFactory(this);
202         _stmtPoolFactory = stmtPoolFactory;
203         _validationQuery = validationQuery;
204         _defaultReadOnly = defaultReadOnly;
205         _defaultAutoCommit = defaultAutoCommit;
206         _defaultTransactionIsolation = defaultTransactionIsolation;
207         _defaultCatalog = defaultCatalog;
208     }
209 
210     /**
211      * Sets the {@link ConnectionFactory} from which to obtain base {@link Connection}s.
212      * @param connFactory the {@link ConnectionFactory} from which to obtain base {@link Connection}s
213      */
214     synchronized public void setConnectionFactory(ConnectionFactory connFactory) {
215         _connFactory = connFactory;
216     }
217 
218     /**
219      * Sets the query I use to {@link #validateObject validate} {@link Connection}s.
220      * Should return at least one row.
221      * Using <tt>null</tt> turns off validation.
222      * @param validationQuery a query to use to {@link #validateObject validate} {@link Connection}s.
223      */
224     synchronized public void setValidationQuery(String validationQuery) {
225         _validationQuery = validationQuery;
226     }
227 
228     /**
229      * Sets the {@link ObjectPool} in which to pool {@link Connection}s.
230      * @param pool the {@link ObjectPool} in which to pool those {@link Connection}s
231      */
232     synchronized public void setPool(ObjectPool pool) {
233         if(null != _pool && pool != _pool) {
234             try {
235                 _pool.close();
236             } catch(Exception e) {
237                 // ignored !?!
238             }
239         }
240         _pool = pool;
241     }
242 
243     public ObjectPool getPool() {
244         return _pool;
245     }
246 
247     /**
248      * Sets the {@link KeyedObjectPoolFactory} I use to create {@link KeyedObjectPool}s
249      * for pooling {@link java.sql.PreparedStatement}s.
250      * Set to <tt>null</tt> to disable {@link java.sql.PreparedStatement} pooling.
251      * @param stmtPoolFactory the {@link KeyedObjectPoolFactory} to use to create {@link KeyedObjectPool}s for pooling {@link java.sql.PreparedStatement}s
252      */
253     synchronized public void setStatementPoolFactory(KeyedObjectPoolFactory stmtPoolFactory) {
254         _stmtPoolFactory = stmtPoolFactory;
255     }
256 
257     /**
258      * Sets the default "read only" setting for borrowed {@link Connection}s
259      * @param defaultReadOnly the default "read only" setting for borrowed {@link Connection}s
260      */
261     public void setDefaultReadOnly(boolean defaultReadOnly) {
262         _defaultReadOnly = defaultReadOnly ? Boolean.TRUE : Boolean.FALSE;
263     }
264 
265     /**
266      * Sets the default "auto commit" setting for borrowed {@link Connection}s
267      * @param defaultAutoCommit the default "auto commit" setting for borrowed {@link Connection}s
268      */
269     public void setDefaultAutoCommit(boolean defaultAutoCommit) {
270         _defaultAutoCommit = defaultAutoCommit;
271     }
272 
273     /**
274      * Sets the default "Transaction Isolation" setting for borrowed {@link Connection}s
275      * @param defaultTransactionIsolation the default "Transaction Isolation" setting for returned {@link Connection}s
276      */
277     public void setDefaultTransactionIsolation(int defaultTransactionIsolation) {
278         _defaultTransactionIsolation = defaultTransactionIsolation;
279     }
280 
281     /**
282      * Sets the default "catalog" setting for borrowed {@link Connection}s
283      * @param defaultCatalog the default "catalog" setting for borrowed {@link Connection}s
284      */
285     public void setDefaultCatalog(String defaultCatalog) {
286         _defaultCatalog = defaultCatalog;
287     }
288     
289     synchronized public Object makeObject() throws Exception {
290         Connection conn = _connFactory.createConnection();
291         if(null != _stmtPoolFactory) {
292             KeyedObjectPool stmtpool = _stmtPoolFactory.createPool();
293             conn = new PoolingConnection(conn,stmtpool);
294             stmtpool.setFactory((PoolingConnection)conn);
295         }
296         return new PoolableConnection(conn,_pool,_config);
297     }
298 
299     public void destroyObject(Object obj) throws Exception {
300         if(obj instanceof PoolableConnection) {
301             ((PoolableConnection)obj).reallyClose();
302         }
303     }
304 
305     public boolean validateObject(Object obj) {
306         if(obj instanceof Connection) {
307             try {
308                 validateConnection((Connection) obj);
309                 return true;
310             } catch(Exception e) {
311                 return false;
312             }           
313         } else {
314             return false;
315         }
316     }
317 
318     public void validateConnection(Connection conn) throws SQLException {
319         String query = _validationQuery;
320         if(conn.isClosed()) {
321             throw new SQLException("validateConnection: connection closed");
322         }
323         if(null != query) {
324             Statement stmt = null;
325             ResultSet rset = null;
326             try {
327                 stmt = conn.createStatement();
328                 rset = stmt.executeQuery(query);
329                 if(!rset.next()) {
330                     throw new SQLException("validationQuery didn't return a row");
331                 }
332             } finally {
333                 try {
334                     rset.close();
335                 } catch(Exception t) {
336                     // ignored
337                 }
338                 try {
339                     stmt.close();
340                 } catch(Exception t) {
341                     // ignored
342                 }
343 
344             }
345         }
346     }
347 
348     public void passivateObject(Object obj) throws Exception {
349         if(obj instanceof Connection) {
350             Connection conn = (Connection)obj;
351             if(!conn.getAutoCommit() && !conn.isReadOnly()) {
352                 conn.rollback();
353             }
354             conn.clearWarnings();
355             conn.setAutoCommit(true);
356         }
357         if(obj instanceof DelegatingConnection) {
358             ((DelegatingConnection)obj).passivate();
359         }
360     }
361 
362     public void activateObject(Object obj) throws Exception {
363         if(obj instanceof DelegatingConnection) {
364             ((DelegatingConnection)obj).activate();
365         }
366         if(obj instanceof Connection) {
367             Connection conn = (Connection)obj;
368             conn.setAutoCommit(_defaultAutoCommit);
369             if (_defaultTransactionIsolation != UNKNOWN_TRANSACTIONISOLATION) {
370                 conn.setTransactionIsolation(_defaultTransactionIsolation);
371             }
372             if (_defaultReadOnly != null) {
373                 conn.setReadOnly(_defaultReadOnly.booleanValue());
374             }
375             if (_defaultCatalog != null) {
376                 conn.setCatalog(_defaultCatalog);
377             }
378         }
379     }
380 
381     protected ConnectionFactory _connFactory = null;
382     protected String _validationQuery = null;
383     protected ObjectPool _pool = null;
384     protected KeyedObjectPoolFactory _stmtPoolFactory = null;
385     protected Boolean _defaultReadOnly = null;
386     protected boolean _defaultAutoCommit = true;
387     protected int _defaultTransactionIsolation = UNKNOWN_TRANSACTIONISOLATION;
388     protected String _defaultCatalog;
389     
390     /**
391      * @deprecated AbandonedConfig is now deprecated.
392      */
393     protected AbandonedConfig _config = null;
394 
395     /**
396      * Internal constant to indicate the level is not set. 
397      */
398   static final int UNKNOWN_TRANSACTIONISOLATION = -1;
399 }