1 23 package com.sun.enterprise.distributedtx; 24 25 import java.util.*; 26 import javax.transaction.*; 27 import javax.transaction.xa.*; 28 29 import com.sun.enterprise.ComponentInvocation; 30 import com.sun.enterprise.resource.*; 31 import com.sun.enterprise.util.i18n.StringManager; 32 33 import java.util.logging.*; 35 import com.sun.logging.*; 36 38 39 40 47 public final class J2EETransactionManagerOpt 48 extends J2EETransactionManagerImpl 49 { 50 51 static Logger _logger=LogDomains.getLogger(LogDomains.JTA_LOGGER); 53 private static StringManager sm = StringManager.getManager(J2EETransactionManagerOpt.class); 56 private ThreadLocal transactions; 59 private ThreadLocal localCallCounter; 60 private Hashtable globalTransactions; 61 private static com.sun.jts.CosTransactions.RWLock freezeLock = new com.sun.jts.CosTransactions.RWLock(); 63 65 public J2EETransactionManagerOpt() { 66 super(); 67 transactions = new ThreadLocal (); 68 localCallCounter = new ThreadLocal (); 69 globalTransactions = new Hashtable(); 70 } 71 72 public void clearThreadTx() { 73 transactions.set(null); 74 } 75 76 77 78 79 80 public boolean enlistResource(Transaction tran, ResourceHandle h) 81 throws RollbackException, IllegalStateException , SystemException 82 { 83 if ( !h.isTransactional() ) 84 return true; 85 86 if(h.isEnlistmentSuspended()){ 88 return false; 89 } 90 91 if ( !(tran instanceof J2EETransaction) ) 92 return super.enlistResource(tran, h); 93 94 J2EETransaction tx = (J2EETransaction)tran; 95 96 if(_logger.isLoggable(Level.FINE)) { 97 _logger.log(Level.FINE,"\n\nIn J2EETransactionManagerOpt.enlistResource, h=" +h+" h.xares="+h.getXAResource()+" h.alloc=" 98 +h.getResourceAllocator()+" tx="+tx); 99 } 100 101 if ( (tx.getNonXAResource()!=null) && (!useLAO || (useLAO && !h.supportsXA()))) { 102 boolean isSameRM=false; 103 try { 104 isSameRM = h.getXAResource().isSameRM(tx.getNonXAResource().getXAResource()); 105 } catch ( XAException xex ) { 106 throw new SystemException(sm.getString("enterprise_distributedtx.samerm_excep",xex)); 107 } catch ( Exception ex ) { 108 throw new SystemException(sm.getString("enterprise_distributedtx.samerm_excep",ex)); 109 } 110 if ( !isSameRM ) { 111 throw new IllegalStateException (sm.getString("enterprise_distributedtx.already_has_nonxa")); 112 } 113 } 114 115 if (monitoringEnabled) { 116 tx.addResourceName(h.getResourceSpec().getResourceId()); 117 } 118 119 if ( h.supportsXA() ) { 120 if ( tx.isLocalTx() ) { 121 startJTSTx(tx); 122 if(useLAO) { 125 if(tx.getNonXAResource()!=null && (tx.getLAOResource()==null) ) { 126 tx.setLAOResource(tx.getNonXAResource()); 127 super.enlistLAOResource(tx, tx.getNonXAResource()); 128 } 129 } 130 } 131 return super.enlistResource(tx, h); 132 } 133 else { if (tx.isImportedTransaction()) 135 throw new IllegalStateException (sm.getString("enterprise_distributedtx.nonxa_usein_jts")); 136 if (tx.getNonXAResource() == null) { 137 tx.setNonXAResource(h); 138 } 139 if ( tx.isLocalTx() ) { 140 try { 146 h.getXAResource().start(tx.getLocalXid(), 0); 147 } catch ( XAException ex ) { 148 throw new RuntimeException (sm.getString("enterprise_distributedtx.xaresource_start_excep"),ex); 149 } 150 151 poolmgr.resourceEnlisted(tx, h); 152 return true; 153 } 154 else { 155 if(useLAO) { 156 return super.enlistResource(tx, h); 157 } 158 else { 159 throw new IllegalStateException (sm.getString("enterprise_distributedtx.nonxa_usein_jts")); 160 } 161 } 162 } 163 } 164 165 void startJTSTx(J2EETransaction tx) 166 throws RollbackException, IllegalStateException , SystemException 167 { 168 try { 169 if (tx.isAssociatedTimeout()) { 170 int timeout = tx.cancelTimerTask(); 173 int newtimeout = (int) ((System.currentTimeMillis() - tx.getStartTime()) / 1000); 174 newtimeout = (timeout - newtimeout); 175 super.begin(newtimeout); 176 } 177 else { 178 super.begin(); 179 } 180 if (tx!=null && monitoringEnabled){ 183 if(activeTransactions.remove(tx)){ 184 m_transInFlight--; 185 } 186 } 187 } catch ( NotSupportedException ex ) { 189 throw new RuntimeException (sm.getString("enterprise_distributedtx.lazy_transaction_notstarted"),ex); 190 } 191 Transaction jtsTx = super.getTransaction(); 192 tx.setJTSTx(jtsTx); 193 jtsTx.registerSynchronization(new JTSSynchronization(jtsTx, this)); 194 globalTransactions.put(jtsTx, tx); 195 } 196 197 public boolean delistResource(Transaction tran, ResourceHandle h, int flag) 198 throws IllegalStateException , SystemException 199 { 200 if (!h.isTransactional()) return true; 201 if ( !(tran instanceof J2EETransaction) ) 202 return super.delistResource(tran, h, flag); 203 204 J2EETransaction tx = (J2EETransaction)tran; 205 if ( tx.isLocalTx() ) { 206 try { 208 h.getXAResource().end(tx.getLocalXid(), flag); 209 } catch ( XAException ex ) { 210 throw new RuntimeException (sm.getString("enterprise_distributedtx.xaresource_end_excep", ex)); 211 } 212 return true; 213 } 214 else 215 return super.delistResource(tx, h, flag); 216 } 217 218 219 224 public void checkTransactionImport() { 225 int[] count = (int[])localCallCounter.get(); 227 if ( count != null && count[0] > 0 ) { 228 count[0]--; 229 return; 230 } 231 else { 232 clearThreadTx(); 235 } 236 } 237 238 244 public void checkTransactionExport(boolean isLocal) { 245 246 if ( isLocal ) { 247 int[] count = (int[])localCallCounter.get(); 250 if ( count == null ) { 251 count = new int[1]; 252 localCallCounter.set(count); 253 } 254 count[0]++; 255 return; 256 } 257 258 J2EETransaction tx = (J2EETransaction)transactions.get(); 259 if ( tx == null ) 260 return; 261 262 if ( !tx.isLocalTx() ) return; 264 265 if ( tx.getNonXAResource() != null ) 268 throw new RuntimeException (sm.getString("enterprise_distributedtx.cannot_export_transaction_having_nonxa")); 269 270 try { 273 startJTSTx(tx); 274 } catch ( RollbackException rlex ) { 275 throw new RuntimeException (sm.getString("enterprise_distributedtx.unable_tostart_JTSTransaction"),rlex); 276 } catch ( IllegalStateException isex ) { 277 throw new RuntimeException (sm.getString("enterprise_distributedtx.unable_tostart_JTSTransaction"),isex); 278 } catch ( SystemException ex ) { 279 throw new RuntimeException (sm.getString("enterprise_distributedtx.unable_tostart_JTSTransaction"),ex); 280 } catch ( Exception excep ) { 281 throw new RuntimeException (sm.getString("enterprise_distributedtx.unable_tostart_JTSTransaction"),excep); 282 } 283 } 284 285 286 287 288 289 290 public void begin() throws NotSupportedException, SystemException { 292 begin(getEffectiveTimeout()); 293 } 294 295 301 public void begin(int timeout) throws NotSupportedException, SystemException { 302 if ( transactions.get() != null ) 304 throw new NotSupportedException(sm.getString("enterprise_distributedtx.notsupported_nested_transaction")); 305 306 if ( super.getStatus() != Status.STATUS_NO_TRANSACTION ) 309 throw new NotSupportedException(sm.getString("enterprise_distributedtx.notsupported_nested_transaction")); 310 boolean acquiredlock = false; 312 if(monitoringEnabled){ 313 freezeLock.acquireReadLock(); 314 acquiredlock = true; 315 } 316 try{ 317 J2EETransaction tx = null; 318 if (timeout > 0) 319 tx = new J2EETransaction(timeout); 320 else 321 tx = new J2EETransaction(); 322 transactions.set(tx); 323 if (monitoringEnabled) { 324 activeTransactions.addElement(tx); 325 m_transInFlight++; 326 ComponentInvocation inv = invMgr.getCurrentInvocation(); 327 if (inv != null && inv.getInstance() != null) { 328 tx.setComponentName(inv.getInstance().getClass().getName()); 329 } 330 } 331 }finally{ 332 if(acquiredlock){ 333 freezeLock.releaseReadLock(); 334 } 335 } 336 } 338 339 public void commit() throws RollbackException, 340 HeuristicMixedException, HeuristicRollbackException, SecurityException , 341 IllegalStateException , SystemException { 342 343 try { 344 J2EETransaction tx = (J2EETransaction)transactions.get(); 345 if ( tx != null && tx.isLocalTx()) { 346 Object obj = null; 348 boolean acquiredlock = false; 349 if(monitoringEnabled){ 350 obj = tx; 351 } 352 try{ 353 if(monitoringEnabled){ 354 freezeLock.acquireReadLock(); 355 acquiredlock = true; 356 } 357 tx.commit(); if (monitoringEnabled){ 359 monitorTxCompleted(obj, true); 360 } 361 }catch(RollbackException e){ 362 if (monitoringEnabled){ 363 monitorTxCompleted(obj, false); 364 } 365 throw e; 366 }catch(HeuristicRollbackException e){ 367 if (monitoringEnabled){ 368 monitorTxCompleted(obj, false); 369 } 370 throw e; 371 }catch(HeuristicMixedException e){ 372 if (monitoringEnabled){ 373 monitorTxCompleted(obj, true); 374 } 375 throw e; 376 }finally{ 377 if(acquiredlock){ 378 freezeLock.releaseReadLock(); 379 } 380 } 381 } 382 else { 383 super.commit(); } 385 } finally { 386 transactions.set(null); } 388 } 390 391 public void rollback() throws IllegalStateException , SecurityException , 392 SystemException { 393 boolean acquiredlock=false; 395 try { 396 J2EETransaction tx = (J2EETransaction)transactions.get(); 397 if ( tx != null && tx.isLocalTx()) { 398 Object obj = null; 399 if(monitoringEnabled){ 400 obj = tx; 401 } 402 if(monitoringEnabled){ 403 freezeLock.acquireReadLock(); 404 acquiredlock = true; 405 } 406 tx.rollback(); if(monitoringEnabled){ 408 monitorTxCompleted(obj, false); 409 } 410 } 411 else { 412 super.rollback(); } 414 } finally { 415 transactions.set(null); if(acquiredlock){ 417 freezeLock.releaseReadLock(); 418 } 419 } 420 } 422 423 424 public int getStatus() throws SystemException { 425 J2EETransaction tx = (J2EETransaction)transactions.get(); 426 if ( tx != null && tx.isLocalTx()) 427 return tx.getStatus(); 428 else 429 return super.getStatus(); 430 } 431 432 public Transaction getTransaction() throws SystemException { 433 J2EETransaction tx = (J2EETransaction)transactions.get(); 434 if ( tx != null ) 435 return tx; 436 else { Transaction jtsTx = super.getTransaction(); 438 if ( jtsTx == null ) 439 return null; 440 else { 441 tx = (J2EETransaction)globalTransactions.get(jtsTx); 444 if ( tx == null ) { 445 tx = new J2EETransaction(jtsTx); 446 tx.setImportedTransaction(); 447 try { 448 jtsTx.registerSynchronization( 449 new JTSSynchronization(jtsTx, this)); 450 } catch ( RollbackException rlex ) { 451 throw new SystemException(rlex.toString()); 452 } catch ( IllegalStateException isex ) { 453 throw new SystemException(isex.toString()); 454 } catch ( Exception ex ) { 455 throw new SystemException(ex.toString()); 456 } 457 458 globalTransactions.put(jtsTx, tx); 459 } 460 transactions.set(tx); return tx; 462 } 463 } 464 } 465 466 public void setRollbackOnly() 467 throws IllegalStateException , SystemException { 468 469 J2EETransaction tx = (J2EETransaction)transactions.get(); 470 if ( tx != null && tx.isLocalTx()){ 472 boolean acquiredlock=false; 473 if(monitoringEnabled){ 474 freezeLock.acquireReadLock(); 475 acquiredlock = true; 476 } 477 try{ 478 tx.setRollbackOnly(); 479 }finally{ 480 if(acquiredlock){ 481 freezeLock.releaseReadLock(); 482 } 483 } 484 } 485 else 486 super.setRollbackOnly(); } 489 490 491 public Transaction suspend() throws SystemException { 492 J2EETransaction tx = (J2EETransaction)transactions.get(); 493 if ( tx != null ) { 494 if ( !tx.isLocalTx() ) 495 super.suspend(); 496 transactions.set(null); 497 return tx; 498 } 499 else { 500 return super.suspend(); } 502 } 503 504 public void resume(Transaction tobj) 505 throws InvalidTransactionException, IllegalStateException , 506 SystemException { 507 508 J2EETransaction tx = (J2EETransaction)transactions.get(); 509 if ( tx != null ) 510 throw new IllegalStateException (sm.getString("enterprise_distributedtx.transaction_exist_on_currentThread")); 511 if ( tobj instanceof J2EETransaction ) { 512 J2EETransaction j2eeTx = (J2EETransaction)tobj; 513 if ( !j2eeTx.isLocalTx() ) 514 super.resume(j2eeTx.getJTSTx()); 515 516 transactions.set(tobj); 517 } 518 else { 519 super.resume(tobj); } 521 } 522 523 public boolean isTimedOut() { 524 J2EETransaction tx = (J2EETransaction)transactions.get(); 525 if ( tx != null) 526 return tx.isTimedout(); 527 else 528 return false; 529 } 530 534 public synchronized void freeze(){ 535 super.freeze(); 536 if(freezeLock.isWriteLocked()){ 537 return; 539 } 540 freezeLock.acquireWriteLock(); 541 } 542 545 public synchronized void unfreeze(){ 546 super.unfreeze(); 547 if(freezeLock.isWriteLocked()){ 548 freezeLock.releaseWriteLock(); 549 } 550 } 551 552 554 private class JTSSynchronization implements Synchronization { 555 private Transaction jtsTx; 556 private J2EETransactionManagerOpt j2eeTM; 557 558 JTSSynchronization(Transaction jtsTx, J2EETransactionManagerOpt j2eeTM){ 559 this.jtsTx = jtsTx; 560 this.j2eeTM = j2eeTM; 561 } 562 563 public void beforeCompletion() {} 564 565 public void afterCompletion(int status) { 566 j2eeTM.globalTransactions.remove(jtsTx); 567 } 568 } 569 } 570 571 | Popular Tags |