1 package com.protomatter.jdbc.pool; 2 3 52 53 import java.io.*; 54 import java.sql.*; 55 import java.util.*; 56 import java.text.MessageFormat ; 57 import com.protomatter.util.*; 58 import com.protomatter.pool.*; 59 import com.protomatter.syslog.*; 60 61 71 public class JdbcConnectionPoolConnection 72 implements ObjectPoolObject, Connection, SyslogChannelAware 73 { 74 77 protected JdbcConnectionPool pool = null; 78 79 82 protected Connection connection = null; 83 84 private boolean isDeleted = false; 85 private boolean isClosed = false; 86 private boolean isValid = true; 87 88 private String url = null; 89 private Properties props = null; 90 91 private String originalCatalog = null; 92 private Map originalTypeMap = null; 93 private int originalTransactionIsolation = -1; 94 private boolean originalAutoCommit = false; 95 private boolean originalReadOnly = false; 96 private boolean canCheckAutoCommit = true; 97 98 private long lastTimeUsed = 0; 100 private JdbcCheckoutExceptionTrace checkoutStackException = null; 101 102 private boolean setCatalog; 104 private boolean setTransactionIsolation; 105 private boolean setAutoCommit; 106 private boolean setReadOnly; 107 private boolean setTypeMap; 108 109 JdbcConnectionPoolConnection(JdbcConnectionPool pool, String url, Properties props) 110 throws SQLException 111 { 112 this.isDeleted = false; 113 this.isClosed = false; 114 this.pool = pool; 115 this.url = url; 116 this.props = props; 117 init(false); 118 } 119 120 123 public JdbcConnectionPool getConnectionPool() 124 { 125 return this.pool; 126 } 127 128 137 public Connection getConnection() 138 { 139 return this.connection; 140 } 141 142 148 public Object getSyslogChannel() 149 { 150 return pool.getSyslogChannel(); 151 } 152 153 156 long getLastTimeUsed() 157 { 158 return this.lastTimeUsed; 159 } 160 161 164 void resetLastTimeUsed() 165 { 166 this.lastTimeUsed = System.currentTimeMillis(); 167 } 168 169 172 void setCheckoutStackTrace(JdbcCheckoutExceptionTrace x) 173 { 174 this.checkoutStackException = x; 175 } 176 177 180 JdbcCheckoutExceptionTrace getCheckoutStackTrace() 181 { 182 return this.checkoutStackException; 183 } 184 185 private void init(boolean verbose) 186 throws SQLException 187 { 188 try 189 { 190 if (verbose) 191 { 192 if (pool.useSyslog()) 193 { 194 Syslog.info(this, MessageFormat.format( 195 PoolResources.getResourceString(MessageConstants.GETTING_CONNECTION_MESSAGE), 196 new Object [] { pool.getName(), url })); 197 } 198 else 199 { 200 PrintWriter writer = DriverManager.getLogWriter(); 201 if (writer != null) 202 { 203 writer.println("JdbcConnectionPool: " + 204 MessageFormat.format(PoolResources.getResourceString(MessageConstants.GETTING_CONNECTION_MESSAGE), 205 new Object [] { pool.getName(), url })); 206 } 207 } 208 } 209 210 this.connection = pool.getDriver().connect(url, props); 213 214 try 215 { 216 originalCatalog = this.connection.getCatalog(); 217 } 218 catch (SQLException cx) 219 { 220 originalCatalog = null; 223 } 224 225 try 226 { 227 originalTypeMap = this.connection.getTypeMap(); 228 } 229 catch (AbstractMethodError error) { 231 originalTypeMap = null; 232 } 233 catch (Exception xx) { 235 originalTypeMap = null; 236 } 237 238 try 241 { 242 originalTransactionIsolation = this.connection.getTransactionIsolation(); 243 } 244 catch (SQLException x) 245 { 246 if (verbose) 247 { 248 if (pool.useSyslog()) 249 { 250 Syslog.info(this, MessageFormat.format(PoolResources.getResourceString(MessageConstants.CANNOT_ASK_ISOLATION_MESSAGE), 251 new Object [] { pool.getName(), x.toString() } )); 252 } 253 else 254 { 255 PrintWriter writer = DriverManager.getLogWriter(); 256 if (writer != null) 257 { 258 writer.println("JdbcConnectionPool: " + 259 MessageFormat.format(PoolResources.getResourceString(MessageConstants.CANNOT_ASK_ISOLATION_MESSAGE), 260 new Object [] { pool.getName(), x.toString() } )); 261 } 262 } 263 } 264 } 265 266 try 267 { 268 originalAutoCommit = this.connection.getAutoCommit(); 269 this.canCheckAutoCommit = true; 270 } 271 catch (SQLException x) 272 { 273 this.canCheckAutoCommit = false; 274 if (verbose) 275 { 276 if (pool.useSyslog()) 277 { 278 Syslog.info(this, MessageFormat.format( 279 PoolResources.getResourceString(MessageConstants.CANNOT_ASK_AUTOCOMMIT_MESSAGE), 280 new Object [] { pool.getName(), x.toString() } )); 281 } 282 else 283 { 284 PrintWriter writer = DriverManager.getLogWriter(); 285 if (writer != null) 286 { 287 writer.println("JdbcConnectionPool: " + 288 MessageFormat.format( 289 PoolResources.getResourceString(MessageConstants.CANNOT_ASK_AUTOCOMMIT_MESSAGE), 290 new Object [] { pool.getName(), x.toString() } )); 291 } 292 } 293 } 294 } 295 296 try 297 { 298 originalReadOnly = this.connection.isReadOnly(); 299 } 300 catch (SQLException x) 301 { 302 if (verbose) 303 { 304 if (pool.useSyslog()) 305 { 306 Syslog.info(this, MessageFormat.format( 307 PoolResources.getResourceString(MessageConstants.CANNOT_ASK_READONLY_MESSAGE), 308 new Object [] { pool.getName(), x.toString() } )); 309 } 310 else 311 { 312 PrintWriter writer = DriverManager.getLogWriter(); 313 if (writer != null) 314 { 315 writer.println("JdbcConnectionPool: " + 316 MessageFormat.format(PoolResources.getResourceString( 317 MessageConstants.CANNOT_ASK_READONLY_MESSAGE), 318 new Object [] { pool.getName(), x.toString() } )); 319 } 320 } 321 } 322 } 323 324 this.isValid = true; 325 } 326 catch (SQLException x) 327 { 328 if (verbose) 329 { 330 if (pool.useSyslog()) 331 { 332 Syslog.info(this, MessageFormat.format( 333 PoolResources.getResourceString(MessageConstants.EXCEPTION_RECREATING_CONNECTION_MESSAGE), 334 new Object [] { pool.getName() } ), x); 335 } 336 else 337 { 338 PrintWriter pw = DriverManager.getLogWriter(); 339 if (pw != null) 340 { 341 pw.println("JdbcConnectionPool: " + 342 MessageFormat.format( 343 PoolResources.getResourceString(MessageConstants.EXCEPTION_RECREATING_CONNECTION_MESSAGE), 344 new Object [] { pool.getName() } )); 345 x.printStackTrace(pw); 346 } 347 } 348 } 349 this.isValid = false; 350 throw x; 351 } 352 } 353 354 359 public void deleteObjectPoolObject() 360 { 361 this.isDeleted = true; 362 this.isValid = false; 363 try 364 { 365 this.connection.close(); 366 } 367 catch (SQLException x) 368 { 369 ; 371 } 372 } 373 374 void reallyClose() 375 { 376 try 378 { 379 this.connection.close(); 380 this.isValid = false; 381 this.isClosed = true; 382 } 383 catch (SQLException x) 384 { 385 ; 386 } 387 } 388 389 405 public synchronized void refresh(boolean verbose) 406 throws SQLException 407 { 408 if (verbose) 409 { 410 if (pool.useSyslog()) 411 { 412 Syslog.info(this, 413 MessageFormat.format(PoolResources.getResourceString(MessageConstants.REFRESHING_CONNECTION_MESSAGE), 414 new Object [] { pool.getName() })); 415 } 416 else 417 { 418 PrintWriter writer = DriverManager.getLogWriter(); 419 if (writer != null) 420 { 421 writer.println("JdbcConnectionPool: " + 422 MessageFormat.format(PoolResources.getResourceString(MessageConstants.REFRESHING_CONNECTION_MESSAGE), 423 new Object [] { pool.getName() })); 424 } 425 } 426 } 427 428 boolean needsRefresh = !validate(verbose); 429 430 if (needsRefresh) 433 { 434 if (verbose) 435 { 436 if (pool.useSyslog()) 437 { 438 Syslog.info(this, 439 MessageFormat.format(PoolResources.getResourceString(MessageConstants.CLOSING_CONNECTION_MESSAGE), 440 new Object [] { pool.getName() })); 441 } 442 else 443 { 444 PrintWriter writer = DriverManager.getLogWriter(); 445 if (writer != null) 446 { 447 writer.println("JdbcConnectionPool: " + 448 MessageFormat.format(PoolResources.getResourceString(MessageConstants.CLOSING_CONNECTION_MESSAGE), 449 new Object [] { pool.getName() })); 450 } 451 } 452 } 453 454 try { this.connection.close(); } catch (SQLException x) { ; } 455 456 init(verbose); 457 458 if (!validate(verbose)) 460 { 461 if (verbose) 462 { 463 if (pool.useSyslog()) 464 { 465 Syslog.info(this, 466 MessageFormat.format(PoolResources.getResourceString(MessageConstants.STILL_NOT_OK_MESSAGE), 467 new Object [] { pool.getName() })); 468 } 469 else 470 { 471 PrintWriter writer = DriverManager.getLogWriter(); 472 if (writer != null) 473 { 474 writer.println("JdbcConnectionPool: " + 475 MessageFormat.format(PoolResources.getResourceString(MessageConstants.STILL_NOT_OK_MESSAGE), 476 new Object [] { pool.getName() })); 477 } 478 } 479 } 480 throw new SQLException( 481 MessageFormat.format(PoolResources.getResourceString(MessageConstants.CONNECTION_INVALID), 482 new Object [] { pool.getName() })); 483 } 484 } 485 else 486 { 487 if (verbose) 488 { 489 if (pool.useSyslog()) 490 { 491 Syslog.info(this, 492 MessageFormat.format(PoolResources.getResourceString(MessageConstants.CONNECTION_OK), 493 new Object [] { pool.getName() })); 494 } 495 else 496 { 497 PrintWriter writer = DriverManager.getLogWriter(); 498 if (writer != null) 499 { 500 writer.println("JdbcConnectionPool: " + 501 MessageFormat.format(PoolResources.getResourceString(MessageConstants.CONNECTION_OK), 502 new Object [] { pool.getName() })); 503 } 504 } 505 } 506 } 507 } 508 509 514 public synchronized void refresh() 515 throws SQLException 516 { 517 refresh(false); 518 } 519 520 526 private boolean validate(boolean verbose) 527 throws SQLException 528 { 529 String statement = pool.getValidityCheckStatement(); 530 if (statement != null) 531 { 532 Statement s = null; 533 ResultSet r = null; 534 try 535 { 536 s = createStatement(); 537 r = s.executeQuery(statement); 538 if (!r.next()) return false; 540 return true; 541 } 542 catch (Exception x) 543 { 544 return false; 545 } 546 finally 547 { 548 if (r != null) try { r.close(); } catch (Exception x) { ; } 549 if (s != null) try { s.close(); } catch (Exception x) { ; } 550 } 551 } 552 return false; 554 } 555 556 561 public boolean isObjectPoolObjectValid() 562 { 563 return isValid; 564 } 565 566 570 public void invalidate() 571 { 572 this.isValid = false; 573 } 574 575 580 public void beforeObjectPoolObjectCheckout() 581 { 582 if (pool.getValidateOnCheckout()) 583 { 584 int numTries = pool.getMaxCheckoutRefreshAttempts(); 585 long sleep = (long)pool.getCheckoutRefreshWaitTime(); 586 587 for (int i=0; i<numTries || numTries < 0; i++) 588 { 589 try 590 { 591 refresh(pool.getVerboseValidate()); 592 return; 593 } 594 catch (SQLException x) 595 { 596 ; } 598 Thread.yield(); 599 if (sleep > 0) 600 { 601 try { Thread.sleep(sleep); } 603 catch (Exception x) { ; } 604 } 605 } 606 invalidate(); 608 } 609 } 610 611 616 public void afterObjectPoolObjectCheckin() 617 { 618 this.isClosed = false; 620 try 621 { 622 clearWarnings(); 623 624 if (setCatalog && (originalCatalog != null)) 625 setCatalog(originalCatalog); 626 setCatalog = false; 627 628 if (setTypeMap) 629 setTypeMap(originalTypeMap); 630 setTypeMap = false; 631 632 if (setTransactionIsolation) 633 setTransactionIsolation(originalTransactionIsolation); 634 setTransactionIsolation = false; 635 636 if (setAutoCommit) 637 setAutoCommit(originalAutoCommit); 638 setAutoCommit = false; 639 640 if (setReadOnly) 641 setReadOnly(originalReadOnly); 642 setReadOnly = false; 643 } 644 catch (SQLException x) 645 { 646 if (pool.useSyslog()) 647 { 648 Syslog.warning(this, 649 MessageFormat.format(PoolResources.getResourceString(MessageConstants.CANNOT_RESET_CONNECTION), 650 new Object [] { pool.getName() }), x); 651 } 652 else 653 { 654 PrintWriter pw = DriverManager.getLogWriter(); 655 pw.println("JdbcConnectionPool: " + 656 MessageFormat.format(PoolResources.getResourceString(MessageConstants.CANNOT_RESET_CONNECTION), 657 new Object [] { pool.getName() })); 658 x.printStackTrace(pw); 659 } 660 661 this.isValid = false; 662 try 663 { 664 this.connection.close(); 665 } 666 catch (SQLException sx) 667 { 668 ; } 670 } 671 } 672 673 private final void checkValid() 674 throws SQLException 675 { 676 if (!this.isValid) 677 throw new SQLException(PoolResources.getResourceString(MessageConstants.CONNECTION_INVALID_REFRESH)); 678 lastTimeUsed = System.currentTimeMillis(); 679 } 680 681 688 public Statement createStatement() 689 throws SQLException 690 { 691 checkValid(); 692 return this.connection.createStatement(); 693 } 694 695 702 public PreparedStatement prepareStatement(String sql) 703 throws SQLException 704 { 705 checkValid(); 706 return this.connection.prepareStatement(sql); 707 } 708 709 716 public CallableStatement prepareCall(String sql) 717 throws SQLException 718 { 719 checkValid(); 720 return this.connection.prepareCall(sql); 721 } 722 723 730 public String nativeSQL(String sql) 731 throws SQLException 732 { 733 checkValid(); 734 return this.connection.nativeSQL(sql); 735 } 736 737 744 public void setAutoCommit(boolean autoCommit) 745 throws SQLException 746 { 747 checkValid(); 748 this.connection.setAutoCommit(autoCommit); 749 this.setAutoCommit = true; 750 } 751 752 759 public boolean getAutoCommit() 760 throws SQLException 761 { 762 checkValid(); 763 return this.connection.getAutoCommit(); 764 } 765 766 773 public void commit() 774 throws SQLException 775 { 776 checkValid(); 777 this.connection.commit(); 778 } 779 780 787 public void rollback() 788 throws SQLException 789 { 790 checkValid(); 791 this.connection.rollback(); 792 } 793 794 812 public void close() 813 throws SQLException 814 { 815 if (isClosed()) 817 return; 818 819 if (this.canCheckAutoCommit) 820 { 821 if (this.connection.getAutoCommit()) 822 { 823 try 824 { 825 this.connection.commit(); 826 } 827 catch (SQLException x) 828 { 829 ; } 833 } 834 else 835 { 836 try 841 { 842 this.connection.rollback(); 843 } 844 catch (SQLException x) 845 { 846 ; 847 } 848 } 849 } 850 851 this.isClosed = true; 852 try 853 { 854 pool.checkin(this); 855 } 856 catch (Exception x) 857 { 858 throw new PoolSQLException(MessageFormat.format( 859 PoolResources.getResourceString(MessageConstants.CANNOT_CHECKIN_CONNECTION_MESSAGE), 860 new Object [] { pool.getName() }), x); 861 } 862 } 863 864 871 public boolean isClosed() 872 throws SQLException 873 { 874 return this.isClosed; 877 } 878 879 886 public DatabaseMetaData getMetaData() 887 throws SQLException 888 { 889 checkValid(); 890 return this.connection.getMetaData(); 891 } 892 893 900 public void setReadOnly(boolean readOnly) 901 throws SQLException 902 { 903 checkValid(); 904 this.connection.setReadOnly(readOnly); 905 this.setReadOnly = true; 906 } 907 908 915 public boolean isReadOnly() 916 throws SQLException 917 { 918 checkValid(); 919 return this.connection.isReadOnly(); 920 } 921 922 929 public void setCatalog(String catalog) 930 throws SQLException 931 { 932 checkValid(); 933 this.connection.setCatalog(catalog); 934 this.setCatalog = true; 935 } 936 937 944 public String getCatalog() 945 throws SQLException 946 { 947 checkValid(); 948 return this.connection.getCatalog(); 949 } 950 951 958 public void setTransactionIsolation(int level) 959 throws SQLException 960 { 961 checkValid(); 962 this.connection.setTransactionIsolation(level); 963 this.setTransactionIsolation = true; 964 } 965 966 973 public int getTransactionIsolation() 974 throws SQLException 975 { 976 checkValid(); 977 return this.connection.getTransactionIsolation(); 978 } 979 980 987 public SQLWarning getWarnings() 988 throws SQLException 989 { 990 checkValid(); 991 return this.connection.getWarnings(); 992 } 993 994 1001 public void clearWarnings() 1002 throws SQLException 1003 { 1004 checkValid(); 1005 this.connection.clearWarnings(); 1006 } 1007 1008 1015 public Statement createStatement(int resultSetType, int resultSetConcurrency) 1016 throws SQLException 1017 { 1018 checkValid(); 1019 return this.connection.createStatement(resultSetType, resultSetConcurrency); 1020 } 1021 1022 1029 public Map getTypeMap() 1030 throws SQLException 1031 { 1032 checkValid(); 1033 return this.connection.getTypeMap(); 1034 } 1035 1036 1043 public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) 1044 throws SQLException 1045 { 1046 checkValid(); 1047 return this.connection.prepareCall(sql, resultSetType, resultSetConcurrency); 1048 } 1049 1050 1057 public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) 1058 throws SQLException 1059 { 1060 checkValid(); 1061 return this.connection.prepareStatement(sql, resultSetType, resultSetConcurrency); 1062 } 1063 1064 1071 public void setTypeMap(Map typeMap) 1072 throws SQLException 1073 { 1074 checkValid(); 1075 this.connection.setTypeMap(typeMap); 1076 this.setTypeMap = true; 1077 } 1078} 1079 | Popular Tags |