KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > avalon > excalibur > datasource > JdbcConnectionPool


1 /*
2  * Copyright (C) The Apache Software Foundation. All rights reserved.
3  *
4  * This software is published under the terms of the Apache Software License
5  * version 1.1, a copy of which has been included with this distribution in
6  * the LICENSE.txt file.
7  */

8 package org.apache.avalon.excalibur.datasource;
9
10 import java.util.HashSet JavaDoc;
11 import java.util.Iterator JavaDoc;
12 import org.apache.avalon.excalibur.concurrent.Lock;
13 import org.apache.avalon.excalibur.pool.DefaultPoolController;
14 import org.apache.avalon.excalibur.pool.HardResourceLimitingPool;
15 import org.apache.avalon.excalibur.pool.Poolable;
16 import org.apache.avalon.framework.activity.Disposable;
17 import org.apache.avalon.framework.activity.Initializable;
18
19 /**
20  * The Pool implementation for JdbcConnections. It uses a background
21  * thread to manage the number of SQL Connections.
22  *
23  * @author <a HREF="mailto:bloritsch@apache.org">Berin Loritsch</a>
24  * @version CVS $Revision: 1.14 $ $Date: 2001/12/21 16:58:06 $
25  * @since 4.0
26  */

27 public class JdbcConnectionPool
28     extends HardResourceLimitingPool
29     implements Runnable JavaDoc, Disposable, Initializable
30 {
31     private Thread JavaDoc m_initThread;
32     private final boolean m_autoCommit;
33     private boolean m_noConnections = false;
34     private long m_wait = -1;
35     private HashSet JavaDoc m_waitingThreads = new HashSet JavaDoc();
36
37     public JdbcConnectionPool( final JdbcConnectionFactory factory, final DefaultPoolController controller, final int min, final int max, final boolean autoCommit)
38         throws Exception JavaDoc
39     {
40         super(factory, controller, max);
41         m_min = min;
42
43         this.m_autoCommit = autoCommit;
44     }
45
46     /**
47      * Set the timeout in milliseconds for blocking when waiting for a
48      * new connection. It defaults to -1. Any number below 1 means that there
49      * is no blocking, and the Pool fails hard. Any number above 0 means we
50      * will wait for that length of time before failing.
51      */

52     public void setTimeout( long timeout )
53     {
54         if (this.m_initialized)
55         {
56             throw new IllegalStateException JavaDoc("You cannot change the timeout after the pool is initialized");
57         }
58
59         m_wait = timeout;
60     }
61
62     public void initialize()
63     {
64         m_initThread = new Thread JavaDoc( this );
65         m_initThread.start();
66     }
67
68     protected final Poolable newPoolable() throws Exception JavaDoc
69     {
70         JdbcConnection conn = null;
71
72         if ( m_wait < 1 )
73         {
74             conn = (JdbcConnection) super.newPoolable();
75         }
76         else
77         {
78             long curMillis = System.currentTimeMillis();
79             long endTime = curMillis + m_wait;
80             while ( ( null == conn ) && ( curMillis < endTime ) )
81             {
82                 Object JavaDoc thread = Thread.currentThread();
83                 m_waitingThreads.add(thread);
84
85                 try
86                 {
87                     curMillis = System.currentTimeMillis();
88                     m_mutex.release();
89
90                     thread.wait( endTime - curMillis );
91                 }
92                 finally
93                 {
94                     m_mutex.acquire();
95                 }
96
97                 try
98                 {
99                     conn = (JdbcConnection) super.newPoolable();
100                 }
101                 finally
102                 {
103                     // Do nothing except keep waiting
104
}
105             }
106         }
107
108         if (null == conn )
109         {
110             throw new NoAvailableConnectionException("All available connections are in use");
111         }
112
113         conn.setPool(this);
114         return conn;
115     }
116
117     public Poolable get()
118         throws Exception JavaDoc
119     {
120         if (! m_initialized)
121         {
122             if (m_noConnections)
123             {
124                 throw new IllegalStateException JavaDoc("There are no connections in the pool, check your settings.");
125             }
126             else if (m_initThread == null)
127             {
128                 throw new IllegalStateException JavaDoc("You cannot get a Connection before the pool is initialized.");
129             }
130             else
131             {
132                 m_initThread.join();
133             }
134         }
135
136         JdbcConnection obj = (JdbcConnection) super.get();
137
138         if (obj.isClosed())
139         {
140             if (getLogger().isDebugEnabled())
141             {
142                 getLogger().debug("JdbcConnection was closed, creating one to take its place");
143             }
144
145             try {
146                 m_mutex.acquire();
147                 if (m_active.contains(obj))
148                 {
149                     m_active.remove(obj);
150                 }
151
152                 this.removePoolable(obj);
153
154                 obj = (JdbcConnection) this.newPoolable();
155
156                 m_active.add(obj);
157             }
158             catch (Exception JavaDoc e)
159             {
160                 if (getLogger().isWarnEnabled())
161                 {
162                     getLogger().warn("Could not get an open connection", e);
163                 }
164                 throw e;
165             }
166             finally
167             {
168                 m_mutex.release();
169             }
170         }
171
172         if (obj.getAutoCommit() != m_autoCommit) {
173             obj.setAutoCommit(m_autoCommit);
174         }
175
176         return obj;
177     }
178
179     public void put( Poolable obj )
180     {
181         super.put( obj );
182         Iterator JavaDoc i = m_waitingThreads.iterator();
183         while (i.hasNext())
184         {
185             Object JavaDoc thread = i.next();
186             thread.notify();
187             i.remove();
188         }
189     }
190
191
192     public void run()
193     {
194         try {
195             this.grow(this.m_min);
196
197             if (this.size() > 0) {
198                 m_initialized = true;
199             } else {
200                 this.m_noConnections = true;
201
202                 if (getLogger().isFatalErrorEnabled())
203                 {
204                     getLogger().fatalError("Excalibur could not create any connections. " +
205                                            "Examine your settings to make sure they are correct. " +
206                                            "Make sure you can connect with the same settings on your machine.");
207                 }
208             }
209         } catch (Exception JavaDoc e) {
210             if (getLogger().isDebugEnabled())
211             {
212                 getLogger().debug("Caught an exception during initialization", e);
213             }
214         }
215     }
216 }
217
Popular Tags