1 23 package com.lutris.appserver.server.sql.standard; 24 25 import java.lang.reflect.Constructor ; 26 import java.sql.SQLException ; 27 import java.util.Date ; 28 import java.util.Hashtable ; 29 import java.util.LinkedList ; 30 import java.util.NoSuchElementException ; 31 32 import org.enhydra.dods.CommonConstants; 33 import org.enhydra.dods.DODS; 34 35 import com.lutris.appserver.server.sql.AbstractDBConnectionFactory; 36 import com.lutris.appserver.server.sql.ConnectionAllocator; 37 import com.lutris.appserver.server.sql.DBConnection; 38 import com.lutris.appserver.server.sql.ExtendedConnectionAllocator; 39 import com.lutris.appserver.server.sql.ExtendedDBConnection; 40 import com.lutris.appserver.server.sql.LogicalDatabase; 41 import com.lutris.appserver.server.sql.SimpleDBConnectionFactory; 42 import com.lutris.logging.Logger; 43 import com.lutris.util.Config; 44 import com.lutris.util.ConfigException; 45 import com.lutris.util.KeywordValueException; 46 47 114 125 public class SimpleConnectionAllocator implements ExtendedConnectionAllocator { 127 128 132 protected LogicalDatabase logicalDatabase = null; 133 134 137 protected String url; 138 139 142 protected String user; 143 144 147 protected String password; 148 149 150 153 protected String shutDownStr; 154 155 160 private int maxPoolSize; 161 162 165 private int currentPoolSize; 166 167 170 private long connectionIdileTimeout = -1; 171 172 175 private int biggestPoolSize; 176 177 180 private Date biggestPoolDate; 181 182 185 protected long numRequests; 186 187 190 194 private LinkedList pool; 195 196 205 private Hashtable connectionUsageCounter; 206 207 210 protected int maxWaitingConnections; 211 212 213 218 private int maxConnectionUsages = -1; 219 220 224 protected boolean sqlLogging; 225 226 229 private int timeOut; 230 231 235 protected int queryTimeOut; 236 237 241 protected int transactionTimeOut; 242 243 247 protected int maxPreparedStatements; 248 249 253 protected int generation = 1; 254 255 256 261 protected DBConnection createConnection() 262 throws java.sql.SQLException { 263 DBConnection dbConnection = dbConnectionFactory.createConnection((ConnectionAllocator)this, url, user, 264 password, maxPreparedStatements, sqlLogging, generation); 265 return dbConnection; 266 } 267 268 private AbstractDBConnectionFactory dbConnectionFactory = null; 269 private String dbConnectionFactoryName = null; 270 private AbstractDBConnectionFactory createDBConnectionFactory(String factoryName){ 271 Class connectionFactoryClass = null; 272 Constructor connectionFactoryConstructor = null; 273 Class [] methodTypes={}; 274 Object [] methodArgs={}; 275 AbstractDBConnectionFactory factory = null; 276 if (factoryName!=null){ 277 try{ 278 connectionFactoryClass = Class.forName(factoryName); 279 factory = (AbstractDBConnectionFactory)connectionFactoryClass.newInstance(); 280 }catch(Exception e){ 281 DODS.getLogChannel().write(Logger.INFO,"Faild to make Connection Factory :"+factoryName+" creating StandardDBConnectionFactory insted"); 282 factory = null; 283 } 284 } 285 if (factoryName==null || factory == null){ 286 factory = new SimpleDBConnectionFactory(); 287 } 288 return factory; 289 290 } 291 292 301 public SimpleConnectionAllocator(LogicalDatabase logicalDatabase, 302 Config conConfig) 303 throws ConfigException { 304 this.logicalDatabase = logicalDatabase; 305 try { 306 url = conConfig.getString("Url"); 307 user = conConfig.getString("User"); 308 password = conConfig.getString("Password"); 309 timeOut = conConfig.getInt("AllocationTimeout", 1000); 310 maxPoolSize = conConfig.getInt("MaxPoolSize", 0); 311 sqlLogging = conConfig.getBoolean("Logging", false); 312 queryTimeOut = conConfig.getInt("QueryTimeout", 0); 313 transactionTimeOut = conConfig.getInt("TransactionTimeout", 0); 314 connectionIdileTimeout = conConfig.getLong("ConnectionIdleTimeout", -1); 315 316 shutDownStr = conConfig.getString("ShutDownString",null); 317 318 maxPreparedStatements = conConfig.getInt("MaxPreparedStatements", -1); 319 maxConnectionUsages = conConfig.getInt("MaxConnectionUsages", -1); 321 maxWaitingConnections = conConfig.getInt("MaxWaitingConnections", Integer.MAX_VALUE); 323 324 dbConnectionFactoryName = conConfig.getString(CommonConstants.CONNECTION_FACTORY,null); 325 326 dbConnectionFactory = createDBConnectionFactory(dbConnectionFactoryName); 327 328 329 } catch (KeywordValueException except) { 330 throw new ConfigException("Bad DatabaseManager.DB." 331 + logicalDatabase.getName() 332 + ".Connection section defined in config file."); 333 } 334 currentPoolSize = 0; 335 339 pool = new LinkedList (); 340 if (maxConnectionUsages > 0) { 341 connectionUsageCounter = new Hashtable (); 342 } 343 biggestPoolSize = 0; 345 biggestPoolDate = new Date (); 346 numRequests = 0; 347 } 348 349 357 public synchronized DBConnection allocate() 358 throws SQLException { 359 boolean createNewConn = true; 367 371 DBConnection conn = null; 372 373 while (conn == null) { 374 while (pool.isEmpty()) { 375 if (createNewConn 377 && ((currentPoolSize < maxPoolSize) 378 || (maxPoolSize <= 0))) { 379 try { 380 384 DBConnection newConnection = createConnection(); 385 386 if (connectionUsageCounter != null) { 387 connectionUsageCounter.put(newConnection, 388 new Integer (maxConnectionUsages)); 389 } 390 pool.addLast(newConnection); 391 currentPoolSize++; 393 if (currentPoolSize > biggestPoolSize) { 394 biggestPoolSize = currentPoolSize; 395 biggestPoolDate = new Date (); 396 } 397 } catch (SQLException e) { 398 if (currentPoolSize > 0) { 399 DODS.getLogChannel().write(Logger.INFO, 400 "ConnectionAllocator: " 401 + "failed to allocate a new connection due to" 402 + e.toString() + "Error code: " 403 + e.getErrorCode() + "\n" + "SQLState: " 404 + e.getSQLState() + "\n" 405 + "\nCurrent pool size is: " 406 + currentPoolSize 407 + "\nMaximum configured pool size is now " 408 + maxPoolSize + "\nContinuing...\n"); 409 createNewConn = false; 410 } else { 411 DODS.getLogChannel().write(Logger.EMERGENCY, 412 "ConnectionAllocator: " 413 + "failed to allocate a new connection" 414 + "\nThe connection pool is empty!\n"); 415 throw e; 416 } 417 } 418 } else { 419 try { 420 if (timeOut > 0) { 421 wait(timeOut); 422 426 if (pool.isEmpty()) { 427 DODS.getLogChannel().write(Logger.EMERGENCY, 429 "ConnectionAllocator: " 430 + "allocation of a new connection timed out." 431 + "Possible dead lock avoided."); 432 String msg = "Connections are currently unavailable.\n" 433 + "Possible dead lock avoided."; 434 435 throw new SQLException (msg); 436 } 437 } else { 438 wait(); 439 } 440 } catch (InterruptedException intEx) {} 441 } 442 } 443 450 try { 452 conn = (DBConnection) pool.removeFirst(); 453 } catch (NoSuchElementException e) {} 454 if (connectionUsageCounter != null) { 455 Integer connUsages = (Integer ) connectionUsageCounter.get(conn); 456 457 if (connUsages != null && connUsages.intValue() > 0) { 458 connectionUsageCounter.put(conn, 460 new Integer (connUsages.intValue() - 1)); 461 } else { conn.close(); 463 currentPoolSize--; 464 connectionUsageCounter.remove(conn); 465 DODS.getLogChannel().write(Logger.DEBUG, 466 "ConnectionAllocator: connection closed due to usage counter. currentPoolSize=" 467 + currentPoolSize + "\n"); 468 conn = null; 469 } 470 } 471 if ((conn!=null) && (conn.getConnection().isClosed())){ 472 conn.close(); 473 currentPoolSize--; 474 if (connectionUsageCounter!=null && connectionUsageCounter.contains(conn)){ 475 connectionUsageCounter.remove(conn); 476 } 477 DODS.getLogChannel().write(Logger.DEBUG, 478 "ConnectionAllocator: Inactiv connection closed due allocate() operation. Geting new one. currentPoolSize=" 479 + currentPoolSize + "\n"); 480 conn = null; 481 } 482 if((conn != null)&&(connectionIdileTimeout>0)){ 483 if((System.currentTimeMillis() 484 -((ExtendedDBConnection)conn).getConnectionEnterPoolTime()) 485 >connectionIdileTimeout){ 486 conn.close(); 487 currentPoolSize--; 488 DODS.getLogChannel().write(Logger.DEBUG, 489 "ConnectionAllocator: Connection closed due allocate() operation - long connection idile time. Geting new one. currentPoolSize=" 490 + currentPoolSize + "\n"); 491 conn = null; 492 } 493 } 494 } 495 conn.allocate(); 498 return conn; 499 } 500 501 507 public synchronized void release(DBConnection dbConnection) { 508 try { 509 if ( (dbConnection.getGeneration() < generation) 510 || (dbConnection.isMarkedForDrop()) 511 || (dbConnection.getConnection().isClosed()) 512 || (pool.size() >=maxWaitingConnections) ) { 513 dbConnection.close(); 514 dbConnection = null; 515 currentPoolSize--; 516 } 517 else { 518 522 if (connectionIdileTimeout>0){ 523 ((ExtendedDBConnection)dbConnection).setConnectionEnterPoolTime(System.currentTimeMillis()); 524 } 525 pool.addLast(dbConnection); 526 } 528 } 529 catch (SQLException ex) { 530 DODS.getLogChannel().write(Logger.DEBUG,"Eror relasing connection"); 531 } 532 notify(); 533 } 534 535 550 public synchronized void drop(DBConnection dbConnection) { 551 if (generation <= dbConnection.getGeneration()) { 552 generation++; } 554 572 LinkedList newPool = new LinkedList (); 573 574 try { 575 while (!pool.isEmpty()) { 576 DBConnection connect = (DBConnection) pool.removeFirst(); 577 578 if (connect.getGeneration() < generation) { 579 connect.close(); 580 currentPoolSize--; 581 } else { 582 newPool.addLast(connect); 583 } 584 } 585 } catch (NoSuchElementException e) {} 586 pool = newPool; 589 notify(); 591 } 592 593 597 public synchronized void dropAllNow() { 598 606 607 if (shutDownStr!=null) { 608 try { 609 DBConnection tmpConn = allocate(); 610 tmpConn.execute(shutDownStr); 611 tmpConn.release(); 612 } catch (SQLException e1) {} 613 } 614 try { 615 while (!pool.isEmpty()) { 616 DBConnection connect = (DBConnection) pool.removeFirst(); 617 618 connect.close(); 619 currentPoolSize--; 620 } 621 } catch (NoSuchElementException e) {} 622 } 624 625 630 public int getActiveCount() { 631 return currentPoolSize; 632 } 633 634 639 public int getMaxCount() { 640 return biggestPoolSize; 641 } 642 643 649 public Date getMaxCountDate() { 650 return biggestPoolDate; 651 } 652 653 656 public void resetMaxCount() { 657 biggestPoolSize = currentPoolSize; 658 biggestPoolDate = new Date (); 659 } 660 661 666 public long getRequestCount() { 667 return numRequests; 668 } 669 670 675 protected void finalize() { 676 dropAllNow(); 677 } 678 679 683 public String getDatabaseName() { 684 return logicalDatabase.getName(); 685 } 686 687 public void IncrementRequesteCount(){ 688 numRequests++; 689 } 690 } 691 | Popular Tags |