1 29 30 package com.caucho.sql; 31 32 import com.caucho.config.ConfigException; 33 import com.caucho.config.types.InitParam; 34 import com.caucho.config.types.Period; 35 import com.caucho.loader.Environment; 36 import com.caucho.loader.EnvironmentClassLoader; 37 import com.caucho.loader.EnvironmentListener; 38 import com.caucho.log.Log; 39 import com.caucho.util.Alarm; 40 import com.caucho.util.AlarmListener; 41 import com.caucho.util.L10N; 42 43 import javax.naming.InitialContext ; 44 import javax.naming.NamingException ; 45 import javax.resource.spi.ManagedConnectionFactory ; 46 import javax.sql.ConnectionPoolDataSource ; 47 import javax.sql.XADataSource ; 48 import javax.transaction.TransactionManager ; 49 import java.io.PrintWriter ; 50 import java.sql.Driver ; 51 import java.sql.SQLException ; 52 import java.util.ArrayList ; 53 import java.util.HashMap ; 54 import java.util.Iterator ; 55 import java.util.logging.Level ; 56 import java.util.logging.Logger ; 57 58 106 public class DBPoolImpl implements AlarmListener, EnvironmentListener { 107 protected static final Logger log = Log.open(DBPoolImpl.class); 108 private static final L10N L = new L10N(DBPoolImpl.class); 109 110 114 private static final String URL_PREFIX = "jdbc:caucho:" ; 115 116 120 public static final String PROPERTY_USER = "user" ; 121 125 public static final String PROPERTY_PASSWORD = "password" ; 126 127 private static final long MAX_IDLE_TIME = 30000; 129 130 private String _name; 131 132 private ArrayList <DriverConfig> _driverList 133 = new ArrayList <DriverConfig>(); 134 135 private ArrayList <DriverConfig> _backupDriverList 136 = new ArrayList <DriverConfig>(); 137 138 private ConnectionConfig _connectionConfig 139 = new ConnectionConfig(); 140 141 private ManagedConnectionFactory _mcf; 143 144 private String _user; 145 private String _password; 146 147 private int _maxConnections = 128; 149 private long _maxIdleTime = MAX_IDLE_TIME; 151 private long _maxActiveTime = 6L * 3600L * 1000L; 153 private long _maxPoolTime = 24L * 3600L * 1000L; 155 156 private long _connectionWaitTime = 600 * 1000; 158 private int _connectionWaitCount = (int) (_connectionWaitTime / 1000); 159 160 private int _maxOverflowConnections = 0; 162 163 private boolean _isStarted; 165 private boolean _isClosed; 167 private boolean _forbidClose; 169 170 private String _pingTable; 172 private String _pingQuery; 174 private boolean _isPing; 176 private long _pingInterval = 1000; 178 179 private boolean _isTransactional = true; 181 private boolean _isXAForbidSameRM = false; 183 private TransactionManager _tm; 185 private long _transactionTimeout = 0; 187 188 private boolean _isSpy; 189 private int _spyId; 190 191 private int _maxCloseStatements = 256; 192 private int _preparedStatementCacheSize = 0; 194 195 private boolean _isWrapStatements = true; 196 197 200 private int _idCount; 202 203 private Alarm _alarm; 205 206 210 public DBPoolImpl() 211 { 212 } 213 214 217 public String getName() 218 { 219 return _name; 220 } 221 222 226 public void setName(String name) 227 { 228 _name = name; 229 } 230 231 public String getURL() 232 { 233 return _driverList.get(0).getURL(); 234 } 235 236 239 public DriverConfig createDriver() 240 { 241 DriverConfig driver = new DriverConfig(this); 242 243 _driverList.add(driver); 244 245 return driver; 246 } 247 248 251 public DriverConfig createBackupDriver() 252 { 253 DriverConfig driver = new DriverConfig(this); 254 255 _backupDriverList.add(driver); 256 257 return driver; 258 } 259 260 263 public void setInitParam(InitParam init) 264 { 265 DriverConfig driver = _driverList.get(0); 266 267 HashMap <String ,String > params = init.getParameters(); 268 269 Iterator <String > iter = params.keySet().iterator(); 270 while (iter.hasNext()) { 271 String key = iter.next(); 272 driver.setInitParam(key, params.get(key)); 273 } 274 } 275 276 279 public void setJDBCDriver(Driver jdbcDriver) 280 throws SQLException 281 { 282 DriverConfig driver; 283 284 if (_driverList.size() > 0) 285 driver = _driverList.get(0); 286 else 287 driver = createDriver(); 288 289 driver.setDriver(jdbcDriver); 290 } 291 292 295 public ConnectionConfig createConnection() 296 { 297 return _connectionConfig; 298 } 299 300 303 public ConnectionConfig getConnectionConfig() 304 { 305 return _connectionConfig; 306 } 307 308 311 public void setPoolDataSource(ConnectionPoolDataSource poolDataSource) 312 throws SQLException 313 { 314 DriverConfig driver; 315 316 if (_driverList.size() > 0) 317 driver = _driverList.get(0); 318 else 319 driver = createDriver(); 320 321 driver.setPoolDataSource(poolDataSource); 322 } 323 324 327 public void setXADataSource(XADataSource xaDataSource) 328 throws SQLException 329 { 330 DriverConfig driver; 331 332 if (_driverList.size() > 0) 333 driver = _driverList.get(0); 334 else 335 driver = createDriver(); 336 337 driver.setXADataSource(xaDataSource); 338 } 339 340 343 public void setURL(String url) 344 throws ConfigException 345 { 346 DriverConfig driver; 347 348 if (_driverList.size() > 0) 349 driver = _driverList.get(0); 350 else 351 throw new ConfigException(L.l("The driver must be assigned before the URL.")); 352 353 driver.setURL(url); 354 } 355 356 359 public String getUser() 360 { 361 return _user; 362 } 363 364 367 public void setUser(String user) 368 { 369 _user = user; 370 } 371 372 375 public String getPassword() 376 { 377 return _password; 378 } 379 380 383 public void setPassword(String password) 384 { 385 _password = password; 386 } 387 388 391 public int getMaxConnections() 392 { 393 return _maxConnections; 394 } 395 396 399 public void setMaxConnections(int maxConnections) 400 { 401 _maxConnections = maxConnections; 402 } 403 404 407 public int getTotalConnections() 408 { 409 return 0; 411 } 412 413 416 public void setConnectionWaitTime(Period waitTime) 417 { 418 long period = waitTime.getPeriod(); 419 420 _connectionWaitTime = period; 421 422 if (period < 0) 423 _connectionWaitCount = 3600; else { 425 _connectionWaitCount = (int) ((period + 999) / 1000); 426 427 if (_connectionWaitCount <= 0) 428 _connectionWaitCount = 1; 429 } 430 } 431 432 435 public long getConnectionWaitTime() 436 { 437 return _connectionWaitTime; 438 } 439 440 444 public void setMaxOverflowConnections(int maxOverflowConnections) 445 { 446 _maxOverflowConnections = maxOverflowConnections; 447 } 448 449 453 public int getMaxOverflowConnections() 454 { 455 return _maxOverflowConnections; 456 } 457 458 461 public void setTransactionTimeout(Period period) 462 { 463 _transactionTimeout = period.getPeriod(); 464 } 465 466 469 public long getTransactionTimeout() 470 { 471 return _transactionTimeout; 472 } 473 474 477 public void setMaxCloseStatements(int max) 478 { 479 _maxCloseStatements = max; 480 } 481 482 485 public int getMaxCloseStatements() 486 { 487 return _maxCloseStatements; 488 } 489 490 493 public void setWrapStatements(boolean isWrap) 494 { 495 _isWrapStatements = isWrap; 496 } 497 498 501 public boolean isWrapStatements() 502 { 503 return _isWrapStatements; 504 } 505 506 509 public int getPreparedStatementCacheSize() 510 { 511 return _preparedStatementCacheSize; 512 } 513 514 517 public void setPreparedStatementCacheSize(int size) 518 { 519 _preparedStatementCacheSize = size; 520 } 521 522 526 public long getMaxIdleTime() 527 { 528 if (_maxIdleTime > Long.MAX_VALUE / 2) 529 return -1; 530 else 531 return _maxIdleTime; 532 } 533 534 538 public void setMaxIdleTime(Period idleTime) 539 { 540 long period = idleTime.getPeriod(); 541 542 if (period < 0) 543 _maxIdleTime = Long.MAX_VALUE / 2; 544 else if (period < 1000L) 545 _maxIdleTime = 1000L; 546 else 547 _maxIdleTime = period; 548 } 549 550 554 public long getMaxPoolTime() 555 { 556 if (_maxPoolTime > Long.MAX_VALUE / 2) 557 return -1; 558 else 559 return _maxPoolTime; 560 } 561 562 566 public void setMaxPoolTime(Period maxPoolTime) 567 { 568 long period = maxPoolTime.getPeriod(); 569 570 if (period < 0) 571 _maxPoolTime = Long.MAX_VALUE / 2; 572 else if (period == 0) 573 _maxPoolTime = 1000L; 574 else 575 _maxPoolTime = period; 576 } 577 578 581 public long getMaxActiveTime() 582 { 583 if (_maxActiveTime > Long.MAX_VALUE / 2) 584 return -1; 585 else 586 return _maxActiveTime; 587 } 588 589 592 public void setMaxActiveTime(Period maxActiveTime) 593 { 594 long period = maxActiveTime.getPeriod(); 595 596 if (period < 0) 597 _maxActiveTime = Long.MAX_VALUE / 2; 598 else if (period == 0) 599 _maxActiveTime = 1000L; 600 else 601 _maxActiveTime = period; 602 } 603 604 607 public String getPingTable() 608 { 609 return _pingTable; 610 } 611 612 617 public void setPingTable(String pingTable) 618 { 619 _pingTable = pingTable; 620 621 if (pingTable != null) 622 _pingQuery = "select 1 from " + pingTable + " where 1=0"; 623 else 624 _pingQuery = null; 625 } 626 627 630 public String getPingQuery() 631 { 632 return _pingQuery; 633 } 634 635 638 public boolean getPingOnReuse() 639 { 640 return _isPing; 641 } 642 643 646 public void setPingOnReuse(boolean pingOnReuse) 647 { 648 _isPing = pingOnReuse; 649 } 650 651 654 public boolean getPingOnIdle() 655 { 656 return _isPing; 657 } 658 659 662 public void setPingOnIdle(boolean pingOnIdle) 663 { 664 _isPing = pingOnIdle; 665 } 666 667 670 public void setPing(boolean ping) 671 { 672 _isPing = ping; 673 } 674 675 678 public boolean isPing() 679 { 680 return _isPing; 681 } 682 683 686 public void setPingInterval(Period interval) 687 { 688 _pingInterval = interval.getPeriod(); 689 690 if (_pingInterval < 0) 691 _pingInterval = Long.MAX_VALUE / 2; 692 else if (_pingInterval < 1000) 693 _pingInterval = 1000; 694 } 695 696 699 public long getPingInterval() 700 { 701 return _pingInterval; 702 } 703 704 707 public void setTransactionManager(TransactionManager tm) 708 { 709 _tm = tm; 710 } 711 712 715 721 722 725 public boolean isXA() 726 { 727 return _isTransactional; 728 } 729 730 733 public void setXA(boolean isTransactional) 734 { 735 _isTransactional = isTransactional; 736 } 737 738 741 public boolean isXAForbidSameRM() 742 { 743 return _isXAForbidSameRM; 744 } 745 746 749 public void setXAForbidSameRM(boolean isXAForbidSameRM) 750 { 751 _isXAForbidSameRM = isXAForbidSameRM; 752 } 753 754 757 public void setSpy(boolean isSpy) 758 { 759 _isSpy = isSpy; 760 } 761 762 765 public boolean isSpy() 766 { 767 return _isSpy; 768 } 769 770 773 public int newSpyId() 774 { 775 return _spyId++; 776 } 777 778 781 public boolean isTransactional() 782 { 783 return _isTransactional; 784 } 785 786 790 public boolean isXATransaction() 791 { 792 if (_connectionConfig.isReadOnly()) 793 return false; 794 else if (_driverList.size() > 0) { 795 DriverConfig driver = _driverList.get(0); 796 797 return driver.isXATransaction(); 798 } 799 else 800 return false; 801 } 802 803 807 public boolean isLocalTransaction() 808 { 809 if (_connectionConfig.isReadOnly()) 810 return false; 811 else if (_driverList.size() > 0) { 812 DriverConfig driver = _driverList.get(0); 813 814 return driver.isLocalTransaction(); 815 } 816 else 817 return false; 818 } 819 820 int createPoolId() 821 { 822 return _idCount++; 823 } 824 825 828 public void setLoginTimeout(int seconds) throws SQLException 829 { 830 } 831 832 835 public int getLoginTimeout() throws SQLException 836 { 837 return 0; 838 } 839 842 public void setLogWriter(PrintWriter out) throws SQLException 843 { 844 } 845 846 849 public PrintWriter getLogWriter() throws SQLException 850 { 851 return null; 852 } 853 854 857 public void init() 858 throws Exception 859 { 860 Environment.addEnvironmentListener(this); 861 862 864 874 875 try { 876 if (_tm == null) { 877 Object obj = new InitialContext ().lookup("java:comp/TransactionManager"); 878 879 if (obj instanceof TransactionManager ) 880 _tm = (TransactionManager ) obj; 881 } 882 } catch (Exception e) { 883 log.log(Level.FINE, e.toString(), e); 884 } 885 886 890 891 for (int i = 0; i < _driverList.size(); i++) { 892 DriverConfig driver = _driverList.get(i); 893 894 if (driver.getUser() == null) 895 driver.setUser(_user); 896 if (driver.getPassword() == null) 897 driver.setPassword(_password); 898 899 driver.initDriver(); 900 driver.initDataSource(_isTransactional, _isSpy); 901 902 if (_mcf == null) 903 _mcf = driver.getManagedConnectionFactory(); 904 905 909 } 910 911 DriverConfig []drivers = new DriverConfig[_driverList.size()]; 912 _driverList.toArray(drivers); 913 914 for (int i = 0; i < _backupDriverList.size(); i++) { 915 DriverConfig driver = _backupDriverList.get(i); 916 917 if (driver.getUser() == null) 918 driver.setUser(_user); 919 if (driver.getPassword() == null) 920 driver.setPassword(_password); 921 922 driver.initDriver(); 923 driver.initDataSource(_isTransactional, _isSpy); 924 928 } 929 930 DriverConfig []backupDrivers = new DriverConfig[_backupDriverList.size()]; 931 _backupDriverList.toArray(backupDrivers); 932 933 if (_mcf == null) 934 _mcf = new ManagedFactoryImpl(this, drivers, backupDrivers); 935 936 if (_name != null) { 937 String name = _name; 938 if (! name.startsWith("java:")) 939 name = "java:comp/env/" + name; 940 941 if (drivers[0].getURL() != null) 942 log.config("database " + name + " starting (URL:" + drivers[0].getURL() + ")"); 943 else 944 log.config("database " + name + " starting"); 945 946 } 949 } 950 951 954 ManagedConnectionFactory getManagedConnectionFactory() 955 { 956 return _mcf; 957 } 958 959 968 synchronized void initDataSource() 969 throws SQLException 970 { 971 if (_isStarted) 972 return; 973 974 _isStarted = true; 975 976 for (int i = 0; i < _driverList.size(); i++) { 977 DriverConfig driver = _driverList.get(i); 978 979 driver.initDataSource(_isTransactional, _isSpy); 980 } 981 982 try { 983 if (_isTransactional && _tm == null) { 984 Object obj = new InitialContext ().lookup("java:comp/TransactionManager"); 985 986 if (obj instanceof TransactionManager ) 987 _tm = (TransactionManager ) obj; 988 } 989 } catch (NamingException e) { 990 throw new SQLExceptionWrapper(e); 991 } 992 } 993 994 997 public void closeIdleConnections() 998 { 999 1000 } 1001 1002 1008 public void handleAlarm(Alarm alarm) 1009 { 1010 if (_isClosed) 1011 return; 1012 } 1013 1014 1017 public void environmentStart(EnvironmentClassLoader loader) 1018 { 1019 } 1020 1021 1024 public void environmentStop(EnvironmentClassLoader loader) 1025 { 1026 forceClose(); 1027 } 1028 1029 1032 public boolean isClosed() 1033 { 1034 return _isClosed; 1035 } 1036 1037 1040 public void close() 1041 { 1042 if (_forbidClose) 1043 throw new IllegalStateException ("illegal to call close() for this DBPool"); 1044 forceClose(); 1045 } 1046 1047 1050 public void forceClose() 1051 { 1052 if (_isClosed) 1053 return; 1054 1055 _isClosed = true; 1056 1057 if (log.isLoggable(Level.FINE)) 1058 log.fine("closing pool " + getName()); 1059 } 1060 1061 1064 public String toString() 1065 { 1066 return "DBPoolImpl[" + _name + "]"; 1067 } 1068} 1069 1070 | Popular Tags |