1 16 17 package org.springframework.jca.cci.connection; 18 19 import javax.resource.ResourceException ; 20 import javax.resource.cci.Connection ; 21 import javax.resource.cci.ConnectionFactory ; 22 import javax.resource.cci.ConnectionSpec ; 23 24 import org.apache.commons.logging.Log; 25 import org.apache.commons.logging.LogFactory; 26 27 import org.springframework.jca.cci.CannotGetCciConnectionException; 28 import org.springframework.transaction.support.TransactionSynchronizationAdapter; 29 import org.springframework.transaction.support.TransactionSynchronizationManager; 30 import org.springframework.util.Assert; 31 32 52 public abstract class ConnectionFactoryUtils { 53 54 private static final Log logger = LogFactory.getLog(ConnectionFactoryUtils.class); 55 56 57 70 public static Connection getConnection(ConnectionFactory cf) throws CannotGetCciConnectionException { 71 return getConnection(cf, null); 72 } 73 74 90 public static Connection getConnection(ConnectionFactory cf, ConnectionSpec spec) 91 throws CannotGetCciConnectionException { 92 try { 93 if (spec != null) { 94 Assert.notNull(cf, "No ConnectionFactory specified"); 95 return cf.getConnection(spec); 96 } 97 else { 98 return doGetConnection(cf); 99 } 100 } 101 catch (ResourceException ex) { 102 throw new CannotGetCciConnectionException("Could not get CCI Connection", ex); 103 } 104 } 105 106 118 public static Connection doGetConnection(ConnectionFactory cf) throws ResourceException { 119 Assert.notNull(cf, "No ConnectionFactory specified"); 120 121 ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(cf); 122 if (conHolder != null) { 123 return conHolder.getConnection(); 124 } 125 126 logger.debug("Opening CCI Connection"); 127 Connection con = cf.getConnection(); 128 129 if (TransactionSynchronizationManager.isSynchronizationActive()) { 130 logger.debug("Registering transaction synchronization for CCI Connection"); 131 conHolder = new ConnectionHolder(con); 132 conHolder.setSynchronizedWithTransaction(true); 133 TransactionSynchronizationManager.registerSynchronization(new ConnectionSynchronization(conHolder, cf)); 134 TransactionSynchronizationManager.bindResource(cf, conHolder); 135 } 136 137 return con; 138 } 139 140 148 public static boolean isConnectionTransactional(Connection con, ConnectionFactory cf) { 149 if (cf == null) { 150 return false; 151 } 152 ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(cf); 153 return (conHolder != null && conHolder.getConnection() == con); 154 } 155 156 165 public static void releaseConnection(Connection con, ConnectionFactory cf) { 166 try { 167 doReleaseConnection(con, cf); 168 } 169 catch (ResourceException ex) { 170 logger.debug("Could not close CCI Connection", ex); 171 } 172 catch (Throwable ex) { 173 logger.debug("Unexpected exception on closing CCI Connection", ex); 175 } 176 } 177 178 189 public static void doReleaseConnection(Connection con, ConnectionFactory cf) throws ResourceException { 190 if (con == null || isConnectionTransactional(con, cf)) { 191 return; 192 } 193 con.close(); 194 } 195 196 197 201 private static class ConnectionSynchronization extends TransactionSynchronizationAdapter { 202 203 private final ConnectionHolder connectionHolder; 204 205 private final ConnectionFactory connectionFactory; 206 207 private boolean holderActive = true; 208 209 public ConnectionSynchronization(ConnectionHolder connectionHolder, ConnectionFactory connectionFactory) { 210 this.connectionHolder = connectionHolder; 211 this.connectionFactory = connectionFactory; 212 } 213 214 public void suspend() { 215 if (this.holderActive) { 216 TransactionSynchronizationManager.unbindResource(this.connectionFactory); 217 } 218 } 219 220 public void resume() { 221 if (this.holderActive) { 222 TransactionSynchronizationManager.bindResource(this.connectionFactory, this.connectionHolder); 223 } 224 } 225 226 public void beforeCompletion() { 227 TransactionSynchronizationManager.unbindResource(this.connectionFactory); 228 this.holderActive = false; 229 releaseConnection(this.connectionHolder.getConnection(), this.connectionFactory); 230 } 231 } 232 233 } 234 | Popular Tags |