1 25 26 27 package org.objectweb.jonas.resource; 28 29 import java.io.PrintWriter ; 30 import java.sql.Connection ; 31 import java.sql.PreparedStatement ; 32 import java.sql.ResultSet ; 33 import java.sql.SQLException ; 34 import java.util.Enumeration ; 35 import java.util.HashSet ; 36 import java.util.Hashtable ; 37 import java.util.Iterator ; 38 import java.util.Properties ; 39 import java.util.Set ; 40 import java.util.Vector ; 41 42 import javax.naming.Context ; 43 import javax.naming.NamingException ; 44 import javax.resource.ResourceException ; 45 import javax.resource.spi.ConnectionEvent ; 46 import javax.resource.spi.ConnectionEventListener ; 47 import javax.resource.spi.ConnectionManager ; 48 import javax.resource.spi.ConnectionRequestInfo ; 49 import javax.resource.spi.ManagedConnection ; 50 import javax.resource.spi.ManagedConnectionFactory ; 51 import javax.resource.spi.ResourceAllocationException ; 52 import javax.resource.spi.ValidatingManagedConnectionFactory ; 53 import javax.security.auth.Subject ; 54 import javax.transaction.RollbackException ; 55 import javax.transaction.Transaction ; 56 import javax.transaction.xa.XAResource ; 57 58 import org.objectweb.jonas.resource.pool.api.Pool; 59 import org.objectweb.jonas.resource.pool.api.PoolMatchFactory; 60 import org.objectweb.jonas.resource.pool.lib.HArrayPool; 61 import org.objectweb.jotm.Current; 62 import org.objectweb.jotm.TransactionResourceManager; 63 import org.objectweb.transaction.jta.ResourceManagerEventListener; 64 import org.objectweb.transaction.jta.TransactionManager; 65 import org.objectweb.util.monolog.api.BasicLevel; 66 import org.objectweb.util.monolog.api.Logger; 67 import org.objectweb.util.monolog.api.LoggerFactory; 68 import org.objectweb.util.monolog.wrapper.printwriter.LoggerImpl; 69 70 76 public class ConnectionManagerImpl implements ConnectionEventListener , ConnectionManager , 77 PoolMatchFactory, SQLManager, 78 TransactionResourceManager { 79 80 83 protected static Logger trace = null; 84 87 protected static Logger poolTrace = null; 88 89 93 protected ResourceManagerEventListener rmel = null; 94 95 98 private String resourceBundleName = null; 99 100 103 protected TransactionManager tm; 104 105 109 protected Hashtable mc2mci = null; 110 111 114 private int mcMaxPoolSize = -1; 115 116 119 private int mcMinPoolSize = 0; 120 121 125 private ManagedConnectionFactory mcf; 126 130 private ValidatingManagedConnectionFactory vmcf = null; 131 132 135 protected Pool poolMCs = null; 136 137 141 protected Hashtable usedMCs = null; 142 143 146 static final int MAX_PSTMT_SIZE = 10; 147 148 151 private int maxPstmtPoolSize = MAX_PSTMT_SIZE; 152 153 156 private int jdbcConnLevel = 0; 157 160 private String jdbcConnTestStmt = ""; 161 162 165 protected Vector mcs = new Vector (); 166 167 170 protected Vector synchros = new Vector (); 171 172 176 private ResourceSpec rs = null; 177 178 181 private String transSupport = null; 182 183 186 public final static String RESOURCE_BUNDLE_NAME = "resourceBundleName"; 187 190 public final static String LOGGER = "org.objectweb.util.monolog.logger"; 191 194 public final static String POOL_LOGGER = "org.objectweb.util.monolog.logger_pool"; 195 198 public final static String LOGGER_FACTORY = "org.objectweb.util.monolog.loggerFactory"; 199 202 public final static String TRANSACTION_MANAGER = "transactionManager"; 203 206 public final static String RESOURCE_MANAGER_EVENT_LISTENER = "resourceManagerEventListener"; 207 210 public final static String RESOURCE_ADAPTER = "resourceAdapter"; 211 214 public final static String PRINT_WRITER = "printWriter"; 215 216 219 222 public final static String NO_TRANS_SUPPORT = "NoTransaction"; 223 226 public final static String LOCAL_TRANS_SUPPORT = "LocalTransaction"; 227 230 public final static String XA_TRANS_SUPPORT = "XATransaction"; 231 232 236 public final static int PSWRAP_1 = 1; 237 public final static int PSWRAP_2 = 2; 238 public final static int PSWRAP_3 = 3; 239 public final static int PSWRAP_4 = 4; 240 public final static int PSWRAP_5 = 5; 241 242 246 private ManagedConnection jotmMc = null; 247 250 private XAResource jotmXar = null; 251 254 private String xaName = null; 255 256 259 private boolean isEnabledDebug = false; 260 261 262 266 public ConnectionManagerImpl(String transSupport) { 267 if (transSupport.length() == 0) { 268 transSupport = NO_TRANS_SUPPORT; 269 } else { 270 this.transSupport = transSupport; 271 } 272 } 273 274 280 public void setLogger(Logger l) { 281 trace = l; 282 isEnabledDebug = trace.isLoggable(BasicLevel.DEBUG); 283 } 284 285 286 292 public void setLoggerFactory(LoggerFactory lf) { 293 trace = lf.getLogger("org.objectweb.resource.server"); 294 isEnabledDebug = trace.isLoggable(BasicLevel.DEBUG); 295 } 296 297 298 304 public void setPrintWriter(PrintWriter pw) { 305 trace = new LoggerImpl(pw); 306 } 307 308 309 315 public void setResourceManagerEventListener( 316 ResourceManagerEventListener rmel) { 317 this.rmel = rmel; 318 } 319 320 321 327 public void setTransactionManager(TransactionManager tm) { 328 this.tm = tm; 329 } 330 331 332 340 public void setResourceAdapter(ManagedConnectionFactory tmcf) 341 throws Exception { 342 setResourceAdapter(tmcf, new ConnectionManagerPoolParams()); 343 } 344 345 354 public void setResourceAdapter(ManagedConnectionFactory tmcf, 355 ConnectionManagerPoolParams cmpp) 356 throws Exception { 357 358 if (cmpp.getPoolMax() != 0) { 360 mcMaxPoolSize = cmpp.getPoolMax(); 361 } 362 if (cmpp.getPoolMin() > 0) { 363 mcMinPoolSize = cmpp.getPoolMin(); 364 } 365 366 jdbcConnLevel = cmpp.getJdbcConnLevel(); 368 jdbcConnTestStmt = cmpp.getJdbcConnTestStmt(); 369 370 mcf = tmcf; 371 if (mcf instanceof ValidatingManagedConnectionFactory ) { 372 vmcf = (ValidatingManagedConnectionFactory ) mcf; 373 } 374 375 poolMCs = new HArrayPool(poolTrace); 376 poolMCs.setMatchFactory(this); 377 poolMCs.setMaxSize(mcMaxPoolSize); 378 poolMCs.setMinSize(mcMinPoolSize); 379 poolMCs.setInitSize(cmpp.getPoolInit()); 380 381 if (cmpp.getPoolMaxAge() > 0) { 382 int min = (int) (cmpp.getPoolMaxAge() / 60); 383 poolMCs.setMaxAge(min); 384 } else { 385 poolMCs.setMaxAge(cmpp.getPoolMaxAgeMinutes()); 386 } 387 388 if (cmpp.getPoolMaxOpentime() > 0) { 389 poolMCs.setMaxOpentime(cmpp.getPoolMaxOpentime()); 390 } 391 poolMCs.setMaxWaiters(cmpp.getPoolMaxWaiters()); 392 if (cmpp.getPoolMaxWaittime() > 0) { 393 poolMCs.setMaxWaitTime(cmpp.getPoolMaxWaittime()); 394 } 395 396 poolMCs.startMonitor(); 397 poolMCs.setSamplingPeriod(cmpp.getPoolSamplingPeriod()); 398 maxPstmtPoolSize = cmpp.getPstmtMax(); 399 400 usedMCs = new Hashtable (); 401 rs = new ResourceSpec(null, null); 402 403 if (isEnabledDebug) { 404 trace.log(BasicLevel.DEBUG, ""); 405 } 406 } 407 408 409 424 public void init(Context ctx) throws Exception { 425 mc2mci = new Hashtable (); 426 427 String resourceBundleName = null; 430 try { 431 resourceBundleName = (String ) ctx.lookup(RESOURCE_BUNDLE_NAME); 432 } catch (NamingException e) { 433 } 434 435 try { 437 trace = (Logger) ctx.lookup(LOGGER); 438 poolTrace = (Logger) ctx.lookup(POOL_LOGGER); 439 } catch (NamingException e) { 440 } 441 442 if (trace == null) { 443 try { 444 setLoggerFactory((LoggerFactory) ctx.lookup(LOGGER_FACTORY)); 445 } catch (NamingException e2) { 446 } 447 } 448 if (trace == null) { 449 PrintWriter pw = null; 450 try { 451 pw = (PrintWriter ) ctx.lookup(PRINT_WRITER); 452 } catch (NamingException e3) { 453 } 454 setPrintWriter(pw); 455 } 456 457 if (!transSupport.equalsIgnoreCase(NO_TRANS_SUPPORT)) { 458 tm = (TransactionManager) ctx.lookup(TRANSACTION_MANAGER); 460 } 461 462 try { 464 rmel = (ResourceManagerEventListener) 465 ctx.lookup(RESOURCE_MANAGER_EVENT_LISTENER); 466 } catch (NamingException ne) { 467 } 468 469 try { 472 setResourceAdapter( 473 (ManagedConnectionFactory ) ctx.lookup(RESOURCE_ADAPTER)); 474 } catch (NamingException ne) { 475 } 476 } 477 478 479 484 public void cleanResourceAdapter() throws ResourceException { 485 PreparedStatementWrapper pw = null; 487 while (mcs != null && mcs.size() > 0) { 488 MCInfo mci = (MCInfo) mcs.remove(0); 489 mci.usedCs.clear(); 490 synchronized (mci.pStmts) { 491 while (mci.pStmts != null && mci.pStmts.size() > 0) { 493 pw = (PreparedStatementWrapper) mci.pStmts.remove(0); 494 try { 495 pw.destroy(); 496 } catch (Exception ex) { 497 } 498 } 499 } 500 try { 501 mc2mci.remove(mci.mc); 502 mci.mc.destroy(); 503 } catch (Exception ex) { 504 } 505 } 506 if (usedMCs != null) { 507 for (Enumeration en = usedMCs.keys(); en.hasMoreElements();) { 508 Transaction tx = (Transaction ) en.nextElement(); 509 MCInfo mci = (MCInfo) usedMCs.get(tx); 510 if (mci == null) { 511 continue; 512 } 513 if (mci.rmeCalled) { 514 mci.rme.isValid = false; 515 rmel.connectionClosed(mci.rme); 516 mci.rmeCalled = false; 517 } 518 mci.usedCs.clear(); 519 synchronized (mci.pStmts) { 521 while (mci.pStmts != null && mci.pStmts.size() > 0) { 522 pw = (PreparedStatementWrapper) mci.pStmts.remove(0); 523 try { 524 pw.destroy(); 525 } catch (Exception ex) { 526 } 527 } 528 } 529 try { 530 mc2mci.remove(mci.mc); 531 mci.mc.destroy(); 532 } catch (Exception ex) { 533 } 534 } 535 } 536 while (synchros != null && synchros.size() > 0) { 537 MCInfo mci = (MCInfo) synchros.remove(0); 538 mci.usedCs.clear(); 539 synchronized (mci.pStmts) { 541 while (mci.pStmts != null && mci.pStmts.size() > 0) { 542 pw = (PreparedStatementWrapper) mci.pStmts.remove(0); 543 try { 544 pw.destroy(); 545 } catch (Exception ex) { 546 } 547 } 548 } 549 try { 550 mc2mci.remove(mci.mc); 551 mci.mc.destroy(); 552 } catch (Exception ex) { 553 } 554 } 555 } 556 557 558 565 public Object allocateConnection(ManagedConnectionFactory pMcf, ConnectionRequestInfo cxRequestInfo) 566 throws ResourceException { 567 568 MCInfo mci = null; 569 Transaction currentTx = null; 570 Object connection = null; 571 int retries = 0; 572 Subject subject = null; 573 574 while (connection == null && retries < 20) { 575 if (mcf != pMcf) { 576 throw new ResourceException ( 577 "This ConnectionManager doesn't manage this RA:" + mcf); 578 } 579 580 currentTx = null; 581 try { 582 if (tm != null) { 583 currentTx = tm.getTransaction(); 584 } 585 } catch (Exception e) { 586 trace.log(BasicLevel.ERROR, 587 "Impossible to get the current transaction", e, 588 "ConnectionManagerImpl", "allocateConnection"); 589 } 590 591 mci = (currentTx == null ? null : (MCInfo) usedMCs.get(currentTx)); 593 if (mci != null) { 594 if (mci.mc != null) { 595 if (isEnabledDebug) { 598 trace.log(BasicLevel.DEBUG, "MC (" + mci.mc + ") associated to the current Tx (" + currentTx + ") found"); 599 } 600 Set s = new HashSet (); 601 s.add(mci.mc); 602 if (mci.mc != mcf.matchManagedConnections(s, null, cxRequestInfo)) { 603 throw new ResourceException ( 604 "ConnectionManagerImpl.allocateConnection: illegal state : no mc is matched by mcf"); 605 } 606 if (isEnabledDebug) { 607 trace.log(BasicLevel.DEBUG, "XA Resource " + mci.getXAResource() 608 + " is already enlisted in Tx:" + mci.ctx); 609 } 610 } else { 611 trace.log(BasicLevel.INFO, "remnant of an old failed connection"); 613 mci.ctx = null; 614 mci = null; 615 usedMCs.remove(currentTx); 616 } 617 } 618 619 if (mci == null) { 620 623 rs.cxRequestInfo = cxRequestInfo; 625 if (subject == null && cxRequestInfo != null) { 626 } 628 try { 629 ManagedConnection mc = (ManagedConnection ) poolMCs.getResource(rs); 630 if (mc == null) { 631 throw new ResourceException ("ConnectionManagerImpl.allocateConnection: cannot allocate a ManagedConnection"); 632 } 633 mci = (MCInfo) mc2mci.get(mc); 634 if (mci == null) { 635 mci = new MCInfo(mc); 636 mc2mci.put(mc, mci); 637 } 638 if (isEnabledDebug) { 639 trace.log(BasicLevel.DEBUG, "get a MC from the ra pool, mc=" + mci.mc); 640 } 641 if (transSupport.equalsIgnoreCase(LOCAL_TRANS_SUPPORT)) { 642 if (mci.lw == null) { 643 mci.lw = new LocalXAWrapper(mci.mc.getLocalTransaction(), trace); 644 } 645 } else if (mci.lw != null) { 646 mci.lw = null; 647 } 648 if (!mci.connectionEventListener) { 649 mci.mc.addConnectionEventListener(this); 650 mci.connectionEventListener = true; 651 } 652 mci.synchro = null; 653 if (currentTx != null) { 656 if (isEnabledDebug) { 657 trace.log(BasicLevel.DEBUG, "Enlist the XA Resource " 658 + mci.getXAResource() + " in Tx:" 659 + currentTx); 660 } 661 currentTx.enlistResource(mci.getXAResource()); 662 usedMCs.put(currentTx, mci); 663 mci.ctx = currentTx; 664 } else { 665 mci.ctx = null; 668 mcs.add(mci); 670 if (!transSupport.equalsIgnoreCase(NO_TRANS_SUPPORT)) { 672 mci.rme = new RMEImpl(mci, trace); 673 if (isEnabledDebug) { 674 trace.log(BasicLevel.DEBUG, "Register the managed connection (no tx)"); 675 } 676 if (!mci.rmeCalled) { 678 mci.rme.isValid = true; 679 rmel.connectionOpened(mci.rme); 680 mci.rmeCalled = true; 681 } 682 } 683 } 684 } catch (ResourceException re) { 685 trace.log(BasicLevel.ERROR, re.getMessage(), re); 686 throw re; 687 } catch (Exception e) { 688 String err = "Error related allocation of ManagedConnection"; 689 trace.log(BasicLevel.ERROR, err, e); 690 throw new ResourceException (err, e); 691 } 692 693 } 694 695 connection = mci.mc.getConnection(null, cxRequestInfo); 697 mci.usedCs.add(connection); 699 if (connection instanceof java.sql.Connection ) { 700 try { 701 if (connection instanceof org.objectweb.jonas.jdbc.ConnectionImpl) { 703 ((org.objectweb.jonas.jdbc.ConnectionImpl) connection).setJonasInfo(mci, this); 704 } else { 705 connection = JonasSQLWrapper.createSQLWrapper(connection, mci, this, trace); 706 } 707 if (jdbcConnLevel > 0) { 709 try { 710 if (isEnabledDebug) { 711 trace.log(BasicLevel.DEBUG, "Check the JDBC connection"); 712 } 713 boolean isClosed = true; 714 if (connection instanceof org.objectweb.jonas.jdbc.ConnectionImpl) { 716 isClosed = ((org.objectweb.jonas.jdbc.ConnectionImpl) connection).isPhysicallyClosed(); 717 } else { 718 isClosed = ((Connection ) connection).isClosed(); 719 } 720 if (isClosed) { 721 connectionErrorOccurred(new ConnectionEvent (mci.mc, 722 ConnectionEvent.CONNECTION_ERROR_OCCURRED)); 723 connection = null; 724 retries++; 725 continue; 726 } 727 if (jdbcConnLevel > 1 && jdbcConnTestStmt != null 728 && jdbcConnTestStmt.length() > 0) { 729 if (isEnabledDebug) { 730 trace.log(BasicLevel.DEBUG, "retrying connection: " + jdbcConnTestStmt); 731 } 732 java.sql.Statement stmt = ((Connection ) connection).createStatement(); 733 stmt.execute(jdbcConnTestStmt); 734 stmt.close(); 735 } 736 } catch (Exception e) { 737 trace.log(BasicLevel.ERROR, "Error on connection: removing invalid managed connection " + mci.mc + ": ", e); 738 connectionErrorOccurred(new ConnectionEvent (mci.mc, 739 ConnectionEvent.CONNECTION_ERROR_OCCURRED)); 740 connection = null; 741 retries++; 742 continue; 743 } 744 } 745 } catch (Exception ex) { 746 trace.log(BasicLevel.ERROR, ex.getMessage(), ex); 747 throw new ResourceException (ex); 748 } 749 } 750 751 } 752 if (isEnabledDebug) { 753 trace.log(BasicLevel.DEBUG, "get a logical connection on MC:" + connection); 754 } 755 756 if (connection == null) { 757 if (retries > 0) { 758 throw new ResourceAllocationException ( 759 "Unable to obtain a connection object. Check the validity of the jdbc-test-statement"); 760 } else { 761 throw new ResourceAllocationException ("Unable to obtain a connection object"); 762 } 763 } 764 765 return connection; 766 } 767 768 769 775 public boolean matchResource(Object res, Object hints) { 776 return true; 777 } 778 779 785 public Object matchResource(Set res, Object hints) throws Exception { 786 ResourceSpec spec = (hints != null) ? (ResourceSpec) hints : new ResourceSpec(null, null); 787 return mcf.matchManagedConnections(res, null, spec.cxRequestInfo); 788 } 789 790 791 798 public Object createResource(Object hints) throws Exception { 799 ResourceSpec spec = (hints != null) ? (ResourceSpec) hints : new ResourceSpec(null, null); 800 ManagedConnection mc = mcf.createManagedConnection(spec.subject, 801 spec.cxRequestInfo); 802 if (isEnabledDebug) { 803 trace.log(BasicLevel.DEBUG, "Created MC: " + mc); 804 } 805 return mc; 806 } 807 808 813 public void validateResource(Set res) throws Exception { 814 if (vmcf == null) { 815 return; 816 } 817 try { 818 Set invMcs = vmcf.getInvalidConnections(res); 819 Iterator it = invMcs.iterator(); 820 while (it.hasNext()) { 821 Object obj = it.next(); 822 poolMCs.releaseResource(obj, true, true); 823 } 824 } catch (Exception ex) { 825 if (isEnabledDebug) { 826 trace.log(BasicLevel.DEBUG, "Error trying to validate Connections for " + mcf, ex); 827 } 828 } 829 } 830 831 832 834 public PreparedStatement getPStatement(MCInfo mcinfo, Object conn, String user, String sql) 835 throws SQLException { 836 return getPStatement(mcinfo, conn, user, sql, ResultSet.TYPE_FORWARD_ONLY, 837 ResultSet.CONCUR_READ_ONLY, -1, -1, null, null, PSWRAP_1); 838 839 } 840 841 public PreparedStatement getPStatement(MCInfo mcinfo, Object conn, String user, String sql, 842 int resultSetType, int resultSetConcurrency) 843 throws SQLException { 844 return getPStatement(mcinfo, conn, user, sql, resultSetType, resultSetConcurrency, 845 -1, -1, null, null, PSWRAP_1); 846 } 847 848 public PreparedStatement getPStatement(MCInfo mcinfo, 850 Object conn, 851 String user, String sql, 852 int resultSetType, 853 int resultSetConcurrency, 854 int resultSetHoldability) 855 throws SQLException { 856 return getPStatement(mcinfo, conn, user, sql, resultSetType, resultSetConcurrency, 857 resultSetHoldability, -1, null, null, PSWRAP_2); 858 } 859 860 public PreparedStatement getPStatement(MCInfo mcinfo, 862 Object conn, 863 String user, String sql, 864 int autoGeneratedKeys) 865 throws SQLException { 866 return getPStatement(mcinfo, conn, user, sql, -1, -1, -1, 867 autoGeneratedKeys, null, null, PSWRAP_3); 868 } 869 870 public PreparedStatement getPStatement(MCInfo mcinfo, 872 Object conn, 873 String user, String sql, 874 int[] columnIndexes) 875 throws SQLException { 876 return getPStatement(mcinfo, conn, user, sql, -1, -1, -1, -1, 877 columnIndexes, null, PSWRAP_4); 878 } 879 880 public PreparedStatement getPStatement(MCInfo mcinfo, 882 Object conn, 883 String user, String sql, 884 String [] columnNames) 885 throws SQLException { 886 return getPStatement(mcinfo, conn, user, sql, -1, -1, -1, -1, 887 null, columnNames, PSWRAP_5); 888 } 889 890 891 private PreparedStatement getPStatement(MCInfo mcinfo, 892 Object conn, 893 String user, 894 String sql, 895 int resultSetType, 896 int resultSetConcurrency, 897 int resultSetHoldability, 898 int autoGeneratedKeys, 899 int [] columnIndexes, 900 String [] columnNames, 901 int pswrapType) 902 throws SQLException { 903 904 if (isEnabledDebug) { 905 trace.log(BasicLevel.DEBUG, "Sql: " + sql + " User: " + user); 906 } 907 PreparedStatementWrapper psw = null; 909 switch (pswrapType) { 910 case PSWRAP_1: 911 psw = new PreparedStatementWrapper(user, sql, 912 resultSetType, 913 resultSetConcurrency, 914 trace, 915 isEnabledDebug); 916 break; 917 case PSWRAP_2: 918 psw = new PreparedStatementWrapper(user, sql, 919 resultSetType, 920 resultSetConcurrency, 921 resultSetHoldability, 922 trace, 923 isEnabledDebug); 924 break; 925 case PSWRAP_3: 926 psw = new PreparedStatementWrapper(user, sql, 927 autoGeneratedKeys, 928 trace, 929 isEnabledDebug); 930 break; 931 case PSWRAP_4: 932 psw = new PreparedStatementWrapper(user, sql, 933 columnIndexes, 934 trace, 935 isEnabledDebug); 936 break; 937 case PSWRAP_5: 938 psw = new PreparedStatementWrapper(user, sql, 939 columnNames, 940 trace, 941 isEnabledDebug); 942 break; 943 default: 944 break; 945 } 946 947 synchronized (mcinfo.pStmts) { 948 if (isEnabledDebug) { 949 trace.log(BasicLevel.DEBUG, "MC pStmts: " + mcinfo.pStmts); 950 } 951 int indexPstmt = mcinfo.pStmts.lastIndexOf(psw); 954 if (indexPstmt != -1) { 955 PreparedStatementWrapper ps = (PreparedStatementWrapper) mcinfo.pStmts.remove(indexPstmt); 956 ps.clearPstmtValues(); 957 mcinfo.pStmts.add(ps); return ps; 959 } else if (isEnabledDebug) { 960 trace.log(BasicLevel.DEBUG, "No statement in cache, need to build a new one"); 961 } 962 963 PreparedStatement ps = null; 966 switch (pswrapType) { 967 case PSWRAP_1: 968 ps = ((java.sql.Connection ) conn). 969 prepareStatement(sql, resultSetType, resultSetConcurrency); 970 break; 971 case PSWRAP_2: 972 ps = ((java.sql.Connection ) conn). 973 prepareStatement(sql, resultSetType, resultSetConcurrency, 974 resultSetHoldability); 975 break; 976 case PSWRAP_3: 977 ps = ((java.sql.Connection ) conn). 978 prepareStatement(sql, autoGeneratedKeys); 979 break; 980 case PSWRAP_4: 981 ps = ((java.sql.Connection ) conn). 982 prepareStatement(sql, columnIndexes); 983 break; 984 case PSWRAP_5: 985 ps = ((java.sql.Connection ) conn). 986 prepareStatement(sql, columnNames); 987 break; 988 default: 989 break; 990 } 991 if (maxPstmtPoolSize < 0) { 992 if (isEnabledDebug) { 994 trace.log(BasicLevel.DEBUG, "Pooling is disabled"); 995 } 996 return ps; 997 } else if (maxPstmtPoolSize == 0 || mcinfo.pStmts.size() < maxPstmtPoolSize) { 998 psw.setPreparedStatement(ps); 999 mcinfo.pStmts.add(psw); 1000 if (isEnabledDebug) { 1001 trace.log(BasicLevel.DEBUG, "Adding PStmt: " + psw); 1002 } 1003 return psw; 1004 } else { 1005 int offset = mcinfo.findFreeStmt(); 1006 if (offset >= 0) { 1007 PreparedStatementWrapper pw = (PreparedStatementWrapper) mcinfo.pStmts.remove(offset); 1009 pw.destroy(); 1010 psw.setPreparedStatement(ps); 1011 mcinfo.pStmts.add(psw); 1012 if (isEnabledDebug) { 1013 trace.log(BasicLevel.DEBUG, "Replacing " + pw + " with " + psw); 1014 } 1015 return psw; 1016 } else { 1017 if (isEnabledDebug) { 1019 trace.log(BasicLevel.DEBUG, "No room in pool"); 1020 } 1021 return ps; 1022 } 1023 } 1024 } 1025 } 1026 1027 1028 1033 public void releaseResource(Object rMc) throws Exception { 1034 if (isEnabledDebug) { 1035 trace.log(BasicLevel.DEBUG, "MC: " + rMc); 1036 } 1037 if (rMc instanceof ManagedConnection ) { 1038 ManagedConnection mc = (ManagedConnection ) rMc; 1039 MCInfo mcinfo = (MCInfo) mc2mci.remove(mc); 1040 if (mcinfo != null) { 1041 destroyPStmts(mcinfo); 1042 } 1043 } 1044 } 1045 1046 1051 public void destroyPStmts(MCInfo mcinfo) throws Exception { 1052 if (isEnabledDebug) { 1053 trace.log(BasicLevel.DEBUG, "MCInfo: " + mcinfo); 1054 } 1055 synchronized (mcinfo.pStmts) { 1056 if (mcinfo.pStmts.size() <= 0) { 1057 return; 1058 } 1059 int stmtSize = mcinfo.pStmts.size(); 1060 try { 1061 for (int i = 0; i < stmtSize; i++) { 1062 PreparedStatementWrapper psw = (PreparedStatementWrapper) 1063 mcinfo.pStmts.remove(0); 1064 psw.closePstmt(); 1065 } 1066 } catch (Exception ex) { 1067 throw ex; 1068 } 1069 } 1070 } 1071 1072 1083 public void connectionClosed(ConnectionEvent event) { 1084 ManagedConnection mc = (ManagedConnection ) event.getSource(); 1085 if (mc == null) { 1086 trace.log(BasicLevel.ERROR, "no mc found in Event!"); 1087 } 1088 1089 MCInfo mci = (MCInfo) mc2mci.get(mc); 1090 if (mci == null) { 1091 trace.log(BasicLevel.ERROR, "no mci found!"); 1092 return; 1093 } 1094 1095 if (isEnabledDebug) { 1096 trace.log(BasicLevel.DEBUG, "enter\n" + getState("\t")); 1097 } 1098 1099 mci.usedCs.remove(event.getConnectionHandle()); 1100 1101 if (mci.usedCs.isEmpty()) { 1102 if (isEnabledDebug) { 1103 trace.log(BasicLevel.DEBUG, "Last Connection has just been removed"); 1104 } 1105 1106 try { 1107 Transaction currentTx = null; 1108 if (tm != null) { 1109 currentTx = tm.getTransaction(); 1110 } 1111 1112 if (mci.localTransaction && currentTx == null) { 1113 trace.log(BasicLevel.ERROR, "The managed connection is being closed while a localtransaction is not finished"); 1114 } 1115 1116 if (currentTx != null) { 1117 mci.ctx = currentTx; 1118 1119 if (mci.synchro == null) { 1120 try { 1121 currentTx.registerSynchronization( 1122 new MySynchro(this, mci)); 1123 if (isEnabledDebug) { 1124 trace.log(BasicLevel.DEBUG, "registerSynchro mc=" + mci.mc); 1125 } 1126 } catch (RollbackException e) { 1127 trace.log(BasicLevel.INFO, "registerSynchronization on transaction marked as Rollback only, mc=" + mci.mc); 1130 } 1131 } 1132 } else if (mci.localTransaction) { 1133 if (isEnabledDebug) { 1134 trace.log(BasicLevel.DEBUG, "MC isn't released because local transaction is not finished"); 1135 } 1136 1137 } else { 1138 if (isEnabledDebug) { 1139 trace.log(BasicLevel.DEBUG, "no currentTx"); 1140 } 1141 1142 mcs.remove(mci); 1143 1144 if (mci.ctx != null) { 1145 usedMCs.remove(mci.ctx); 1146 mci.ctx = null; 1147 } 1148 1149 mci.mc.cleanup(); 1150 1151 1154 poolMCs.releaseResource(mci.mc, false, true); 1156 1157 } 1158 if (mci.rmeCalled) { 1159 mci.rme.isValid = false; 1161 rmel.connectionClosed(mci.rme); 1162 mci.rmeCalled = false; 1163 } 1164 } catch (Exception e) { 1165 trace.log(BasicLevel.ERROR, 1166 "an error during delisting of ManagedConection: ", e); 1167 } 1168 if (isEnabledDebug) { 1169 trace.log(BasicLevel.DEBUG, "exit\n" + getState("\t")); 1170 } 1171 } 1172 } 1173 1174 1175 1185 public void connectionErrorOccurred(ConnectionEvent event) { 1186 ManagedConnection mc = (ManagedConnection ) event.getSource(); 1187 if (mc == null) { 1188 trace.log(BasicLevel.ERROR, "no mc found in Event!"); 1189 } 1190 1191 MCInfo mci = (MCInfo) mc2mci.get(mc); 1192 if (mci == null) { 1193 trace.log(BasicLevel.ERROR, "no mci found!"); 1194 return; 1195 } 1196 1197 if (poolTrace.isLoggable(BasicLevel.DEBUG)) { 1198 poolTrace.log(BasicLevel.DEBUG, "enter\n" + getState("\t")); 1199 } 1200 1201 mci.usedCs.clear(); 1202 1203 try { 1204 if (mci.rmeCalled) { 1205 mci.rme.isValid = false; 1207 rmel.connectionErrorOccured(mci.rme); 1208 mci.rmeCalled = false; 1209 } 1210 mc.removeConnectionEventListener(this); 1212 if (mci.ctx != null) { 1214 usedMCs.remove(mci.ctx); 1215 mci.ctx = null; 1216 } else { 1217 mcs.remove(mci); 1218 } 1219 1220 if (isEnabledDebug) { 1221 trace.log(BasicLevel.DEBUG, "Destroying managed connection (" + mc + ")"); 1222 } 1223 destroyPStmts(mci); 1225 1226 poolMCs.releaseResource(mc, true, false); 1227 if (poolTrace.isLoggable(BasicLevel.DEBUG)) { 1228 poolTrace.log(BasicLevel.DEBUG, "enter\n" + getState("\t")); 1229 } 1230 1231 mc2mci.remove(mc); 1232 1233 } catch (Exception e) { 1234 trace.log(BasicLevel.ERROR, 1235 "an error related during delisting of ManagedConection"); 1236 } 1237 } 1238 1239 1240 1246 public void localTransactionCommitted(ConnectionEvent event) { 1247 ManagedConnection mc = (ManagedConnection ) event.getSource(); 1248 if (mc == null) { 1249 trace.log(BasicLevel.ERROR, "no mc found in Event!"); 1250 } 1251 1252 MCInfo mci = (MCInfo) mc2mci.get(mc); 1253 if (mci == null) { 1254 trace.log(BasicLevel.ERROR, "no mci found!"); 1255 return; 1256 } 1257 mci.localTransaction = false; 1258 1259 if (mci.usedCs.isEmpty()) { 1260 if (isEnabledDebug) { 1261 trace.log(BasicLevel.DEBUG, "Close the managed connection"); 1262 } 1263 1264 if (mci.rmeCalled) { 1265 mci.rme.isValid = false; 1267 rmel.connectionClosed(mci.rme); 1268 mci.rmeCalled = false; 1269 } 1270 1271 if (mci.synchro == null) { 1272 mcs.remove(mci); 1273 if (mci.ctx != null) { 1274 usedMCs.remove(mci.ctx); 1275 mci.ctx = null; 1276 } 1277 1278 try { 1279 mci.mc.cleanup(); 1280 1281 poolMCs.releaseResource(mci.mc, false, true); 1283 } catch (Exception e) { 1284 trace.log(BasicLevel.ERROR, 1285 "an error related ManagedConection release", 1286 e, "ConnectionManagerImpl", "localTransactionCommitted"); 1287 } 1288 } 1289 } 1290 } 1291 1292 1293 1299 public void localTransactionRolledback(ConnectionEvent event) { 1300 ManagedConnection mc = (ManagedConnection ) event.getSource(); 1301 if (mc == null) { 1302 trace.log(BasicLevel.ERROR, "no mc found in Event!"); 1303 } 1304 1305 MCInfo mci = (MCInfo) mc2mci.get(mc); 1306 if (mci == null) { 1307 trace.log(BasicLevel.ERROR, "no mci found!"); 1308 return; 1309 } 1310 mci.localTransaction = false; 1311 1312 if (mci.usedCs.isEmpty()) { 1313 if (isEnabledDebug) { 1314 trace.log(BasicLevel.DEBUG, "Close the managed connection"); 1315 } 1316 1317 if (mci.rmeCalled) { 1318 mci.rme.isValid = false; 1320 rmel.connectionClosed(mci.rme); 1321 mci.rmeCalled = false; 1322 } 1323 1324 if (mci.synchro == null) { 1325 mcs.remove(mci); 1326 if (mci.ctx != null) { 1327 usedMCs.remove(mci.ctx); 1328 mci.ctx = null; 1329 } 1330 1331 try { 1332 mci.mc.cleanup(); 1333 1334 poolMCs.releaseResource(mci.mc, false, true); 1336 } catch (Exception e) { 1337 trace.log(BasicLevel.ERROR, 1338 "an error related during ManagedConection release:", 1339 e, "ConnectionManagerImpl", "localTransactionRolledback"); 1340 } 1341 } 1342 } 1343 } 1344 1345 1346 1352 public void localTransactionStarted(ConnectionEvent event) { 1353 ManagedConnection mc = (ManagedConnection ) event.getSource(); 1354 if (mc == null) { 1355 trace.log(BasicLevel.ERROR, "no mc found in Event!"); 1356 } 1357 1358 MCInfo mci = (MCInfo) mc2mci.get(mc); 1359 if (mci == null) { 1360 trace.log(BasicLevel.ERROR, "no mci found!"); 1361 return; 1362 } 1363 mci.localTransaction = true; 1364 } 1365 1366 1367 1372 public String toString() { 1373 String m = super.toString(); 1374 int c1 = 0; 1376 int current = m.indexOf("."); 1377 while (current != -1) { 1378 c1 = current; 1379 current = m.indexOf(".", current + 1); 1380 } 1381 return m.substring(c1 + 1, m.length()); 1382 } 1383 1384 1385 1391 protected String getState(String prefix) { 1392 String res = prefix + "mcf=" + mcf + "\n"; 1393 res += prefix + "ResourceSpec=" + rs.toString() + "\n"; 1394 res += prefix + "size of MC pool:" + poolMCs.getSize() + "\n"; 1395 res += prefix + "size of usedMCs:" + usedMCs.size() + "\n"; 1396 res += prefix + "mcs attached to a tx:\n"; 1397 for (Enumeration en = usedMCs.keys(); en.hasMoreElements();) { 1398 Object tx = en.nextElement(); 1399 MCInfo mci = (MCInfo) usedMCs.get(tx); 1400 res += prefix + "MCI : tx=" + tx + "\n"; 1401 res += mci.getState(prefix + "\t"); 1402 } 1403 res += prefix + "mcs not attached to a tx:\n"; 1404 for (Enumeration en = mcs.elements(); en.hasMoreElements();) { 1405 MCInfo mci = (MCInfo) en.nextElement(); 1406 res += mci.getState(prefix + "\t"); 1407 } 1408 res += prefix + "mcs waiting for tx commit or rollback:\n"; 1409 for (Enumeration en = synchros.elements(); en.hasMoreElements();) { 1410 MCInfo mci = (MCInfo) en.nextElement(); 1411 res += mci.getState(prefix + "\t"); 1412 } 1413 return res; 1414 } 1415 1416 1420 public void setXAName(String xanm) { 1421 xaName = xanm; 1422 } 1423 1424 1428 public String getXAName() { 1429 return (xaName); 1430 } 1431 1432 1435 public void registerXAResource(Properties tmProp) { 1436 if (tm == null) { 1438 return; 1439 } 1440 if (!transSupport.equalsIgnoreCase(XA_TRANS_SUPPORT)) { 1441 return; 1442 } 1443 1444 MCInfo mci = null; 1447 XAResource xar = null; 1448 try { 1449 ManagedConnection mc = (ManagedConnection ) poolMCs.getResource(rs); 1450 if (mc == null) { 1451 if (isEnabledDebug) { 1452 trace.log(BasicLevel.DEBUG, "Cannot allocate a ManagedConnection for registerXAResource"); 1453 } 1454 return; 1455 } 1456 1457 mci = (MCInfo) mc2mci.get(mc); 1458 if (mci == null) { 1459 mci = new MCInfo(mc); 1460 mc2mci.put(mc, mci); 1461 } 1462 1463 xar = mc.getXAResource(); 1464 if (isEnabledDebug) { 1465 trace.log(BasicLevel.DEBUG, "got a MC from the ra pool, mc=" + mci.mc 1466 + " xar=" + xar); 1467 } 1468 1469 if (!mci.connectionEventListener) { 1470 mci.mc.addConnectionEventListener(this); 1471 mci.connectionEventListener = true; 1472 } 1473 1474 mci.synchro = null; 1475 1476 } catch (ResourceException re) { 1477 return; 1478 } catch (Exception e) { 1479 trace.log(BasicLevel.ERROR, e.getMessage(), e); 1480 return; 1481 } 1482 1483 jotmMc = mci.mc; 1485 jotmXar = xar; 1486 1487 try { 1489 if (isEnabledDebug) { 1490 trace.log(BasicLevel.DEBUG, "Registering name = " + xaName + " xar = " + jotmXar); 1491 } 1492 ((Current) tm).getTransactionRecovery().registerResourceManager(xaName, jotmXar, "", tmProp, this); 1493 } catch (Exception ex) { 1494 trace.log(BasicLevel.ERROR, ex.getMessage(), ex); 1495 returnXAResource(xaName, jotmXar); 1496 } 1497 } 1498 1499 1506 public void returnXAResource(String rmName, XAResource rmXares) { 1507 if (isEnabledDebug) { 1510 trace.log(BasicLevel.DEBUG, "Removing name = " + xaName + " xar = " + jotmXar); 1511 } 1512 if (jotmXar == null) { 1513 return; 1514 } 1515 if (!rmXares.equals(jotmXar)) { 1516 trace.log(BasicLevel.ERROR, "XAResource of " + rmXares + " and " 1517 + jotmXar + " not equal!"); 1518 return; 1519 } 1520 1521 MCInfo mci = (MCInfo) mc2mci.get(jotmMc); 1522 if (mci == null) { 1523 trace.log(BasicLevel.ERROR, "no mci found for " + jotmMc); 1524 return; 1525 } 1526 1527 try { 1528 mci.mc.cleanup(); 1529 1530 poolMCs.releaseResource(mci.mc, false, true); 1532 } catch (Exception ex) { 1533 trace.log(BasicLevel.ERROR, ex.getMessage(), ex); 1534 } 1535 1536 jotmMc = null; 1537 jotmXar = null; 1538 } 1539 1540 1542 public Pool getPool() { 1543 return poolMCs; 1544 } 1545 1546 public int getCheckLevel() { 1547 return jdbcConnLevel; 1548 } 1549 1550 public void setCheckLevel(int level) { 1551 jdbcConnLevel = level; 1552 } 1553 1554 public String getTestStatement() { 1555 return jdbcConnTestStmt; 1556 } 1557 1558 public void setTestStatement(String stmt) { 1559 jdbcConnTestStmt = stmt; 1560 } 1561 1562 public int getCurrentInTx() { 1563 return usedMCs.size(); 1564 } 1565} | Popular Tags |