1 8 package org.apache.avalon.excalibur.datasource; 9 10 import java.util.HashSet ; 11 import java.util.Iterator ; 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 27 public class JdbcConnectionPool 28 extends HardResourceLimitingPool 29 implements Runnable , Disposable, Initializable 30 { 31 private Thread m_initThread; 32 private final boolean m_autoCommit; 33 private boolean m_noConnections = false; 34 private long m_wait = -1; 35 private HashSet m_waitingThreads = new HashSet (); 36 37 public JdbcConnectionPool( final JdbcConnectionFactory factory, final DefaultPoolController controller, final int min, final int max, final boolean autoCommit) 38 throws Exception 39 { 40 super(factory, controller, max); 41 m_min = min; 42 43 this.m_autoCommit = autoCommit; 44 } 45 46 52 public void setTimeout( long timeout ) 53 { 54 if (this.m_initialized) 55 { 56 throw new IllegalStateException ("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 ( this ); 65 m_initThread.start(); 66 } 67 68 protected final Poolable newPoolable() throws Exception 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 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 } 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 119 { 120 if (! m_initialized) 121 { 122 if (m_noConnections) 123 { 124 throw new IllegalStateException ("There are no connections in the pool, check your settings."); 125 } 126 else if (m_initThread == null) 127 { 128 throw new IllegalStateException ("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 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 i = m_waitingThreads.iterator(); 183 while (i.hasNext()) 184 { 185 Object 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 e) { 210 if (getLogger().isDebugEnabled()) 211 { 212 getLogger().debug("Caught an exception during initialization", e); 213 } 214 } 215 } 216 } 217 | Popular Tags |