1 3 package jodd.db.pool; 4 5 import jodd.db.DbSqlException; 6 import jodd.db.connection.ConnectionProvider; 7 8 import java.sql.Connection ; 9 import java.sql.DriverManager ; 10 import java.sql.SQLException ; 11 import java.util.ArrayList ; 12 13 22 public class CoreConnectionPool implements Runnable , ConnectionProvider { 23 24 26 private String driver; 27 private String url; 28 private String user; 29 private String password; 30 private int maxConnections = 10; 31 private int minConnections = 5; 32 private boolean waitIfBusy = false; 33 34 public String getDriver() { 35 return driver; 36 } 37 38 public void setDriver(String driver) { 39 this.driver = driver; 40 } 41 42 public String getUrl() { 43 return url; 44 } 45 46 public void setUrl(String url) { 47 this.url = url; 48 } 49 50 public String getUser() { 51 return user; 52 } 53 54 public void setUser(String user) { 55 this.user = user; 56 } 57 58 public String getPassword() { 59 return password; 60 } 61 62 public void setPassword(String password) { 63 this.password = password; 64 } 65 66 public int getMaxConnections() { 67 return maxConnections; 68 } 69 70 public void setMaxConnections(int maxConnections) { 71 this.maxConnections = maxConnections; 72 } 73 74 public int getMinConnections() { 75 return minConnections; 76 } 77 78 public void setMinConnections(int minConnections) { 79 this.minConnections = minConnections; 80 } 81 82 public boolean isWaitIfBusy() { 83 return waitIfBusy; 84 } 85 86 public void setWaitIfBusy(boolean waitIfBusy) { 87 this.waitIfBusy = waitIfBusy; 88 } 89 90 92 private ArrayList availableConnections, busyConnections; 93 private boolean connectionPending = false; 94 95 public CoreConnectionPool() { 96 } 97 98 public void init() { 99 try { 100 Class.forName(driver); 101 } catch (ClassNotFoundException cnfex) { 102 throw new DbSqlException("Database driver not found: '" + driver + '\'', cnfex); 103 } 104 if (minConnections > maxConnections) { 105 minConnections = maxConnections; 106 } 107 availableConnections = new ArrayList (minConnections); 108 busyConnections = new ArrayList (); 109 for (int i = 0; i < minConnections; i++) { 110 try { 111 availableConnections.add(DriverManager.getConnection(url, user, password)); 112 } catch (SQLException sex) { 113 throw new DbSqlException("Unable to get conn from jdbc driver.", sex); 114 } 115 } 116 } 117 118 120 public synchronized Connection getConnection() { 121 if (availableConnections.isEmpty() == false) { 122 int lastIndex = availableConnections.size() - 1; 123 Connection existingConnection = (Connection ) availableConnections.get(lastIndex); 124 availableConnections.remove(lastIndex); 125 126 boolean isClosed; 130 try { 131 isClosed = existingConnection.isClosed(); 132 } catch (SQLException sex) { 133 throw new DbSqlException("Unable to check if database conn is closed.", sex); 134 } 135 if (isClosed) { 136 notifyAll(); return getConnection(); 138 } else { 139 busyConnections.add(existingConnection); 140 return existingConnection; 141 } 142 } else { 143 151 if (((availableConnections.size() + busyConnections.size()) < maxConnections) && !connectionPending) { 152 makeBackgroundConnection(); 153 } else if (!waitIfBusy) { 154 throw new DbSqlException("Connection limit " + maxConnections + " reached."); 155 } 156 try { 159 wait(); 160 } catch (InterruptedException ie) { 161 } 163 return getConnection(); 165 } 166 } 167 168 175 private void makeBackgroundConnection() { 176 connectionPending = true; 177 try { 178 Thread connectThread = new Thread (this); 179 connectThread.start(); 180 } catch (OutOfMemoryError oome) { 181 } 183 } 184 185 public void run() { 186 try { 187 Connection connection = DriverManager.getConnection(url, user, password); 188 synchronized(this) { 189 availableConnections.add(connection); 190 connectionPending = false; 191 notifyAll(); 192 } 193 } catch (Exception ex) { } 196 } 197 198 public synchronized void closeConnection(Connection connection) { 199 busyConnections.remove(connection); 200 availableConnections.add(connection); 201 notifyAll(); } 203 204 205 213 public synchronized int[] getConnectionsCount() { 214 return new int[] {availableConnections.size() + busyConnections.size(), availableConnections.size(), busyConnections.size()}; 215 } 216 217 219 226 public synchronized void close() { 227 closeConnections(availableConnections); 228 availableConnections = new ArrayList (); 229 closeConnections(busyConnections); 230 busyConnections = new ArrayList (); 231 } 232 233 private void closeConnections(ArrayList connections) { 234 try { 235 for (int i = 0; i < connections.size(); i++) { 236 Connection connection = (Connection ) connections.get(i); 237 if (!connection.isClosed()) { 238 connection.close(); 239 } 240 } 241 } catch (SQLException sqle) { 242 } 244 } 245 } 246 | Popular Tags |