1 package org.apache.ojb.broker.accesslayer; 2 3 17 18 import java.sql.Connection ; 19 import java.sql.SQLException ; 20 21 import org.apache.ojb.broker.OJBRuntimeException; 22 import org.apache.ojb.broker.PBKey; 23 import org.apache.ojb.broker.PersistenceBroker; 24 import org.apache.ojb.broker.PersistenceBrokerException; 25 import org.apache.ojb.broker.TransactionAbortedException; 26 import org.apache.ojb.broker.TransactionInProgressException; 27 import org.apache.ojb.broker.TransactionNotInProgressException; 28 import org.apache.ojb.broker.core.PersistenceBrokerImpl; 29 import org.apache.ojb.broker.metadata.JdbcConnectionDescriptor; 30 import org.apache.ojb.broker.metadata.MetadataManager; 31 import org.apache.ojb.broker.platforms.Platform; 32 import org.apache.ojb.broker.platforms.PlatformFactory; 33 import org.apache.ojb.broker.util.batch.BatchConnection; 34 import org.apache.ojb.broker.util.logging.Logger; 35 import org.apache.ojb.broker.util.logging.LoggerFactory; 36 37 44 public class ConnectionManagerImpl implements ConnectionManagerIF 45 { 46 private Logger log = LoggerFactory.getLogger(ConnectionManagerImpl.class); 47 48 private PersistenceBrokerImpl broker = null; 49 private ConnectionFactory connectionFactory; 50 private JdbcConnectionDescriptor jcd; 51 private Platform platform; 52 private Connection con = null; 53 private PBKey pbKey; 54 private boolean originalAutoCommitState; 55 private boolean isInLocalTransaction; 56 private boolean batchMode; 57 private BatchConnection batchCon = null; 58 59 public ConnectionManagerImpl(PersistenceBroker broker) 60 { 61 this.broker = (PersistenceBrokerImpl) broker; 63 this.pbKey = broker.getPBKey(); 64 this.jcd = MetadataManager.getInstance().connectionRepository().getDescriptor(pbKey); 65 this.connectionFactory = ConnectionFactoryFactory.getInstance().createConnectionFactory(); 66 this.platform = PlatformFactory.getPlatformFor(jcd); 67 74 setBatchMode(false); 75 } 76 77 80 public JdbcConnectionDescriptor getConnectionDescriptor() 81 { 82 return jcd; 83 } 84 85 public Platform getSupportedPlatform() 86 { 87 return this.platform; 88 } 89 90 107 public Connection getConnection() throws LookupException 108 { 109 115 if(con != null && !isInLocalTransaction() && !isAlive(con)) 116 { 117 releaseConnection(); 118 } 119 if (con == null) 120 { 121 con = this.connectionFactory.lookupConnection(jcd); 122 if (con == null) throw new PersistenceBrokerException("Cannot get connection for " + jcd); 123 if (jcd.getUseAutoCommit() == JdbcConnectionDescriptor.AUTO_COMMIT_SET_TRUE_AND_TEMPORARY_FALSE) 124 { 125 try 126 { 127 this.originalAutoCommitState = con.getAutoCommit(); 128 } 129 catch (SQLException e) 130 { 131 throw new PersistenceBrokerException("Cannot request autoCommit state on the connection", e); 132 } 133 } 134 if (log.isDebugEnabled()) log.debug("Request new connection from ConnectionFactory: " + con); 135 } 136 137 if (isBatchMode()) 138 { 139 if (batchCon == null) 140 { 141 batchCon = new BatchConnection(con, broker); 142 } 143 return batchCon; 144 } 145 else 146 { 147 return con; 148 } 149 } 150 151 154 public void localBegin() 155 { 156 if (this.isInLocalTransaction) 157 { 158 throw new TransactionInProgressException("Connection is already in transaction"); 159 } 160 Connection connection = null; 161 try 162 { 163 connection = this.getConnection(); 164 } 165 catch (LookupException e) 166 { 167 170 throw new PersistenceBrokerException("Can't lookup a connection", e); 171 } 172 if (log.isDebugEnabled()) log.debug("localBegin was called for con " + connection); 173 if(!broker.isManaged()) 176 { 177 if (jcd.getUseAutoCommit() == JdbcConnectionDescriptor.AUTO_COMMIT_SET_TRUE_AND_TEMPORARY_FALSE) 178 { 179 if (log.isDebugEnabled()) log.debug("Try to change autoCommit state to 'false'"); 180 platform.changeAutoCommitState(jcd, connection, false); 181 } 182 } 183 else 184 { 185 if(log.isDebugEnabled()) log.debug( 186 "Found managed environment setting in PB, will skip Platform.changeAutoCommitState(...) call"); 187 } 188 this.isInLocalTransaction = true; 189 } 190 191 194 public void localCommit() 195 { 196 if (log.isDebugEnabled()) log.debug("commit was called"); 197 if (!this.isInLocalTransaction) 198 { 199 throw new TransactionNotInProgressException("Not in transaction, call begin() before commit()"); 200 } 201 try 202 { 203 if(!broker.isManaged()) 204 { 205 if (batchCon != null) 206 { 207 batchCon.commit(); 208 } 209 else if (con != null) 210 { 211 con.commit(); 212 } 213 } 214 else 215 { 216 if(log.isDebugEnabled()) log.debug( 217 "Found managed environment setting in PB, will skip Connection.commit() call"); 218 } 219 } 220 catch (SQLException e) 221 { 222 log.error("Commit on underlying connection failed, try to rollback connection", e); 223 this.localRollback(); 224 throw new TransactionAbortedException("Commit on connection failed", e); 225 } 226 finally 227 { 228 this.isInLocalTransaction = false; 229 restoreAutoCommitState(); 230 this.releaseConnection(); 231 } 232 } 233 234 237 public void localRollback() 238 { 239 log.info("Rollback was called, do rollback on current connection " + con); 240 if (!this.isInLocalTransaction) 241 { 242 throw new PersistenceBrokerException("Not in transaction, cannot abort"); 243 } 244 try 245 { 246 this.isInLocalTransaction = false; 248 if(!broker.isManaged()) 249 { 250 if (batchCon != null) 251 { 252 batchCon.rollback(); 253 } 254 else if (con != null && !con.isClosed()) 255 { 256 con.rollback(); 257 } 258 } 259 else 260 { 261 if(log.isEnabledFor(Logger.INFO)) log.info( 262 "Found managed environment setting in PB, will ignore rollback call on connection, this should be done by JTA"); 263 } 264 } 265 catch (SQLException e) 266 { 267 log.error("Rollback on the underlying connection failed", e); 268 } 269 finally 270 { 271 try 272 { 273 restoreAutoCommitState(); 274 } 275 catch(OJBRuntimeException ignore) 276 { 277 } 279 releaseConnection(); 280 } 281 } 282 283 286 protected void restoreAutoCommitState() 287 { 288 try 289 { 290 if(!broker.isManaged()) 291 { 292 if (jcd.getUseAutoCommit() == JdbcConnectionDescriptor.AUTO_COMMIT_SET_TRUE_AND_TEMPORARY_FALSE 293 && originalAutoCommitState == true && con != null && !con.isClosed()) 294 { 295 platform.changeAutoCommitState(jcd, con, true); 296 } 297 } 298 else 299 { 300 if(log.isDebugEnabled()) log.debug( 301 "Found managed environment setting in PB, will skip Platform.changeAutoCommitState(...) call"); 302 } 303 } 304 catch (SQLException e) 305 { 306 throw new OJBRuntimeException("Restore of connection autocommit state failed", e); 308 } 309 } 310 311 314 public boolean isAlive(Connection conn) 315 { 316 try 317 { 318 return con != null ? !con.isClosed() : false; 319 } 320 catch (SQLException e) 321 { 322 log.error("IsAlive check failed, running connection was invalid!!", e); 323 return false; 324 } 325 } 326 327 public boolean isInLocalTransaction() 328 { 329 return this.isInLocalTransaction; 330 } 331 332 336 public void releaseConnection() 337 { 338 if (this.con == null) 339 { 340 return; 341 } 342 if(isInLocalTransaction()) 343 { 344 log.error("Release connection: connection is in local transaction, missing 'localCommit' or" + 345 " 'localRollback' call - try to rollback the connection"); 346 localRollback(); 347 } 348 else 349 { 350 this.connectionFactory.releaseConnection(this.jcd, this.con); 351 this.con = null; 352 this.batchCon = null; 353 } 354 } 355 356 360 public ConnectionFactory getUnderlyingConnectionFactory() 361 { 362 return connectionFactory; 363 } 364 365 373 public void setBatchMode(boolean mode) 374 { 375 382 batchMode = mode && jcd.getBatchMode(); 383 } 384 385 388 public boolean isBatchMode() 389 { 390 return batchMode && platform.supportsBatchOperations(); 391 } 392 393 396 public void executeBatch() throws OJBBatchUpdateException 397 { 398 if (batchCon != null) 399 { 400 try 401 { 402 batchCon.executeBatch(); 403 } 404 catch (Throwable th) 405 { 406 throw new OJBBatchUpdateException(th); 407 } 408 } 409 } 410 411 415 public void executeBatchIfNecessary() throws OJBBatchUpdateException 416 { 417 if (batchCon != null) 418 { 419 try 420 { 421 batchCon.executeBatchIfNecessary(); 422 } 423 catch (Throwable th) 424 { 425 throw new OJBBatchUpdateException(th); 426 } 427 } 428 } 429 430 433 public void clearBatch() 434 { 435 if (batchCon != null) 436 { 437 batchCon.clearBatch(); 438 } 439 } 440 } 441 | Popular Tags |