1 18 19 package org.apache.jmeter.protocol.jdbc.util; 20 21 import java.sql.Connection ; 22 import java.sql.DatabaseMetaData ; 23 import java.sql.DriverManager ; 24 import java.sql.SQLException ; 25 import java.util.Hashtable ; 26 import java.util.Map ; 27 28 import org.apache.jmeter.protocol.jdbc.sampler.JDBCSampler; 29 import org.apache.jmeter.testelement.property.JMeterProperty; 30 import org.apache.jorphan.logging.LoggingManager; 31 import org.apache.log.Logger; 32 33 34 38 public class JMeter19ConnectionPool implements ConnectionPool 39 { 40 private static Logger log = LoggingManager.getLoggerForClass(); 41 private static final int ABSOLUTE_MAX_CONNECTIONS = 100; 42 43 public static final String CONNECTIONS = 44 JDBCSampler.JDBCSAMPLER_PROPERTY_PREFIX + "connections"; 45 public static final String MAXUSE = 46 JDBCSampler.JDBCSAMPLER_PROPERTY_PREFIX + "maxuse"; 47 48 private final ConnectionObject connectionArray[]; 49 private final Hashtable rentedConnections = new Hashtable (); 50 51 private final DBKey key; 52 private int maxConnections; 53 54 public JMeter19ConnectionPool(DBKey key, Map properties) 55 throws ConnectionPoolException 56 { 57 this.key = key; 58 59 this.maxConnections = 60 ((JMeterProperty) properties.get(CONNECTIONS)).getIntValue(); 61 int maxUsage = 62 ((JMeterProperty) properties.get(MAXUSE)).getIntValue(); 63 64 validateMaxConnections(); 65 66 connectionArray = new ConnectionObject[maxConnections]; 67 try 68 { 69 for (int i = 0; i < maxConnections; i++) 70 { 71 connectionArray[i] = new ConnectionObject(key, maxUsage); 72 } 73 } 74 catch (SQLException e) 75 { 76 log.error("Error initializing JDBC connection pool", e); 77 throw new ConnectionPoolException( 78 "Error initializing JDBC connection pool: " + e); 79 } 80 } 81 82 83 private void validateMaxConnections() 84 { 85 try 87 { 88 DatabaseMetaData md = 89 DriverManager 90 .getConnection( 91 key.getUrl(), 92 key.getUsername(), 93 key.getPassword()) 94 .getMetaData(); 95 96 int dbMax = md.getMaxConnections(); 97 if (dbMax > 0 && maxConnections > dbMax) 98 { 99 log.warn( 100 "Connection pool configured for " 101 + maxConnections 102 + " but database claims to allow only " 103 + dbMax 104 + ". Reducing the pool size, but problems may occur " 105 + "if multiple connection pools are in use for the " 106 + "same database."); 107 maxConnections = dbMax; 108 } 109 else if (maxConnections > ABSOLUTE_MAX_CONNECTIONS) 110 { 111 maxConnections = ABSOLUTE_MAX_CONNECTIONS; 112 } 113 } 114 catch (Exception e) 115 { 116 log.error("Couldn't get connection to database", e); 117 maxConnections = 0; 118 return; 119 } 120 finally 121 { 122 } 134 } 135 136 140 public Connection getConnection() throws ConnectionPoolException 141 { 142 if (connectionArray.length == 0) 143 { 144 throw new NoConnectionsAvailableException(); 145 } 146 147 Connection c = null; 148 int attempts = 0; 149 while (attempts < 20 && (c = attemptGetConnection()) == null) 150 { 151 try 152 { 153 Thread.sleep(10); 154 } 155 catch (Exception err) 156 { 157 attempts++; 158 } 159 } 160 161 return c; 162 } 163 164 private Connection attemptGetConnection() 165 { 166 Connection c = null; 167 int index = (int) (100 * Math.random()); 168 int count = -1; 169 while (++count < maxConnections && c == null) 170 { 171 index++; 172 c = connectionArray[index % maxConnections].grab(); 173 } 174 175 if (c != null) 176 { 177 rentedConnections.put(c, connectionArray[index % maxConnections]); 178 } 179 180 return c; 181 } 182 186 public void returnConnection(Connection c) 187 { 188 if (c == null) 189 { 190 return; 191 } 192 193 ConnectionObject connOb = (ConnectionObject) rentedConnections.get(c); 194 if (connOb != null) 195 { 196 rentedConnections.remove(c); 197 connOb.release(); 198 } 199 else 200 { 201 log.warn("DBConnectionManager: Lost a connection connection='" + c); 202 c = null; 203 } 204 } 205 206 209 public Connection newConnection(DBKey key) throws SQLException 210 { 211 return DriverManager.getConnection( 212 key.getUrl(), 213 key.getUsername(), 214 key.getPassword()); 215 } 216 217 220 public void close() 221 { 222 for (int i = 0; i < connectionArray.length; i++) 223 { 224 connectionArray[i].close(); 225 connectionArray[i] = null; 226 } 227 } 228 } 229 | Popular Tags |