/* */ package org.jboss.resource.connectionmanager;
/* */
/* */ import EDU.oswego.cs.dl.util.concurrent.SynchronizedBoolean;
/* */ import java.util.ArrayList;
/* */ import java.util.Collection;
/* */ import java.util.HashSet;
/* */ import java.util.Iterator;
/* */ import java.util.Set;
/* */ import javax.management.MBeanServer;
/* */ import javax.management.ObjectName;
/* */ import javax.naming.InitialContext;
/* */ import javax.resource.ResourceException;
/* */ import javax.resource.spi.ConnectionEvent;
/* */ import javax.resource.spi.ConnectionRequestInfo;
/* */ import javax.resource.spi.LocalTransaction;
/* */ import javax.resource.spi.ManagedConnection;
/* */ import javax.security.auth.Subject;
/* */ import javax.transaction.RollbackException;
/* */ import javax.transaction.Synchronization;
/* */ import javax.transaction.SystemException;
/* */ import javax.transaction.Transaction;
/* */ import javax.transaction.TransactionManager;
/* */ import javax.transaction.xa.XAException;
/* */ import javax.transaction.xa.XAResource;
/* */ import javax.transaction.xa.Xid;
/* */ import org.jboss.logging.Logger;
/* */ import org.jboss.resource.JBossResourceException;
/* */ import org.jboss.resource.connectionmanager.xa.XAResourceWrapper;
/* */ import org.jboss.tm.LastResource;
/* */ import org.jboss.tm.TransactionTimeoutConfiguration;
/* */ import org.jboss.tm.TxUtils;
/* */ import org.jboss.util.NestedRuntimeException;
/* */
/* */ public class TxConnectionManager extends BaseConnectionManager2
/* */ implements TxConnectionManagerMBean
/* */ {
/* 132 */ private static final Throwable FAILED_TO_ENLIST = new Throwable("Unabled to enlist resource, see the previous warnings.");
/* */ private ObjectName transactionManagerService;
/* */ private String tmName;
/* */ private TransactionManager tm;
/* 141 */ private boolean trackConnectionByTx = false;
/* */ private boolean localTransactions;
/* 145 */ private int xaResourceTimeout = 0;
/* */ private boolean padXid;
/* */ private boolean wrapXAResource;
/* */ private Boolean isSameRMOverrideValue;
/* */
/* */ protected static void rethrowAsSystemException(String context, Transaction tx, Throwable t)
/* */ throws SystemException
/* */ {
/* 156 */ if ((t instanceof SystemException))
/* 157 */ throw ((SystemException)t);
/* 158 */ if ((t instanceof RuntimeException))
/* 159 */ throw ((RuntimeException)t);
/* 160 */ if ((t instanceof Error))
/* 161 */ throw ((Error)t);
/* 162 */ if ((t instanceof RollbackException))
/* 163 */ throw new IllegalStateException(context + " tx=" + tx + " marked for rollback.");
/* 164 */ throw new NestedRuntimeException(context + " tx=" + tx + " got unexpected error ", t);
/* */ }
/* */
/* */ public TxConnectionManager()
/* */ {
/* */ }
/* */
/* */ public TxConnectionManager(CachedConnectionManager ccm, ManagedConnectionPool poolingStrategy, TransactionManager tm)
/* */ {
/* 186 */ super(ccm, poolingStrategy);
/* 187 */ this.tm = tm;
/* */ }
/* */
/* */ public ObjectName getTransactionManagerService()
/* */ {
/* 192 */ return this.transactionManagerService;
/* */ }
/* */
/* */ public void setTransactionManagerService(ObjectName transactionManagerService)
/* */ {
/* 197 */ this.transactionManagerService = transactionManagerService;
/* */ }
/* */
/* */ /** @deprecated */
/* */ public void setTransactionManager(String tmName)
/* */ {
/* 205 */ this.tmName = tmName;
/* */ }
/* */
/* */ /** @deprecated */
/* */ public String getTransactionManager()
/* */ {
/* 213 */ return this.tmName;
/* */ }
/* */
/* */ public TransactionManager getTransactionManagerInstance()
/* */ {
/* 218 */ return this.tm;
/* */ }
/* */
/* */ public void setTransactionManagerInstance(TransactionManager tm)
/* */ {
/* 223 */ this.tm = tm;
/* */ }
/* */
/* */ public boolean isTrackConnectionByTx()
/* */ {
/* 228 */ return this.trackConnectionByTx;
/* */ }
/* */
/* */ public void setTrackConnectionByTx(boolean trackConnectionByTx)
/* */ {
/* 233 */ this.trackConnectionByTx = trackConnectionByTx;
/* */ }
/* */
/* */ public boolean isLocalTransactions()
/* */ {
/* 238 */ return this.localTransactions;
/* */ }
/* */
/* */ public void setLocalTransactions(boolean localTransactions)
/* */ {
/* 243 */ this.localTransactions = localTransactions;
/* */ }
/* */
/* */ public int getXAResourceTransactionTimeout()
/* */ {
/* 248 */ return this.xaResourceTimeout;
/* */ }
/* */
/* */ public void setXAResourceTransactionTimeout(int timeout)
/* */ {
/* 253 */ this.xaResourceTimeout = timeout;
/* */ }
/* */
/* */ public Boolean getIsSameRMOverrideValue()
/* */ {
/* 263 */ return this.isSameRMOverrideValue;
/* */ }
/* */
/* */ public boolean getWrapXAResource()
/* */ {
/* 268 */ return this.wrapXAResource;
/* */ }
/* */
/* */ public void setWrapXAResource(boolean useXAWrapper)
/* */ {
/* 273 */ this.wrapXAResource = useXAWrapper;
/* */ }
/* */
/* */ public boolean getPadXid()
/* */ {
/* 279 */ return this.padXid;
/* */ }
/* */
/* */ public void setPadXid(boolean padXid)
/* */ {
/* 285 */ this.padXid = padXid;
/* */ }
/* */
/* */ public void setIsSameRMOverrideValue(Boolean isSameRMOverrideValue)
/* */ {
/* 294 */ this.isSameRMOverrideValue = isSameRMOverrideValue;
/* */ }
/* */
/* */ public long getTimeLeftBeforeTransactionTimeout(boolean errorRollback) throws RollbackException
/* */ {
/* 299 */ if (this.tm == null)
/* 300 */ throw new IllegalStateException("No transaction manager: " + this.ccmName);
/* 301 */ if ((this.tm instanceof TransactionTimeoutConfiguration))
/* 302 */ return ((TransactionTimeoutConfiguration)this.tm).getTimeLeftBeforeTransactionTimeout(errorRollback);
/* 303 */ return -1L;
/* */ }
/* */
/* */ protected void startService() throws Exception
/* */ {
/* 308 */ if (this.transactionManagerService != null) {
/* 309 */ this.tm = ((TransactionManager)getServer().getAttribute(this.transactionManagerService, "TransactionManager"));
/* */ }
/* */ else {
/* 312 */ this.log.warn("----------------------------------------------------------");
/* 313 */ this.log.warn("----------------------------------------------------------");
/* 314 */ this.log.warn("Please change your datasource setup to use <depends optional-attribute-name\"TransactionManagerService\">jboss:service=TransactionManager</depends>");
/* 315 */ this.log.warn("instead of <attribute name=\"TransactionManager\">java:/TransactionManager</attribute>");
/* 316 */ this.log.warn("Better still, use a *-ds.xml file");
/* 317 */ this.log.warn("----------------------------------------------------------");
/* 318 */ this.log.warn("----------------------------------------------------------");
/* 319 */ this.tm = ((TransactionManager)new InitialContext().lookup(this.tmName));
/* */ }
/* */
/* 323 */ super.startService();
/* */ }
/* */
/* */ protected void stopService() throws Exception
/* */ {
/* 328 */ this.tm = null;
/* 329 */ super.stopService();
/* */ }
/* */
/* */ public ConnectionListener getManagedConnection(Subject subject, ConnectionRequestInfo cri)
/* */ throws ResourceException
/* */ {
/* 335 */ Transaction trackByTransaction = null;
/* */ try
/* */ {
/* 338 */ Transaction tx = this.tm.getTransaction();
/* 339 */ if ((tx != null) && (!TxUtils.isActive(tx)))
/* 340 */ throw new ResourceException("Transaction is not active: tx=" + tx);
/* 341 */ if (this.trackConnectionByTx)
/* 342 */ trackByTransaction = tx;
/* */ }
/* */ catch (Throwable t)
/* */ {
/* 346 */ JBossResourceException.rethrowAsResourceException("Error checking for a transaction.", t);
/* */ }
/* */
/* 349 */ if (this.trace)
/* 350 */ this.log.trace("getManagedConnection trackByTx=" + this.trackConnectionByTx + " tx=" + trackByTransaction);
/* 351 */ return super.getManagedConnection(trackByTransaction, subject, cri);
/* */ }
/* */
/* */ public void transactionStarted(Collection crs) throws SystemException
/* */ {
/* 356 */ Set cls = new HashSet();
/* 357 */ for (Iterator i = crs.iterator(); i.hasNext(); )
/* */ {
/* 359 */ ConnectionRecord cr = (ConnectionRecord)i.next();
/* 360 */ ConnectionListener cl = cr.cl;
/* 361 */ if (!cls.contains(cl))
/* */ {
/* 363 */ cls.add(cl);
/* 364 */ cl.enlist();
/* */ }
/* */ }
/* */ }
/* */
/* */ protected void managedConnectionReconnected(ConnectionListener cl) throws ResourceException
/* */ {
/* */ try
/* */ {
/* 373 */ cl.enlist();
/* */ }
/* */ catch (Throwable t)
/* */ {
/* 377 */ if (this.trace)
/* 378 */ this.log.trace("Could not enlist in transaction on entering meta-aware object! " + cl, t);
/* 379 */ throw new JBossResourceException("Could not enlist in transaction on entering meta-aware object!", t);
/* */ }
/* */ }
/* */
/* */ protected void managedConnectionDisconnected(ConnectionListener cl) throws ResourceException
/* */ {
/* 385 */ Throwable throwable = null;
/* */ try
/* */ {
/* 388 */ cl.delist();
/* */ }
/* */ catch (Throwable t)
/* */ {
/* 392 */ throwable = t;
/* */ }
/* */
/* 396 */ boolean isFree = cl.isManagedConnectionFree();
/* 397 */ if (this.trace)
/* 398 */ this.log.trace("Disconnected isManagedConnectionFree=" + isFree + " cl=" + cl);
/* 399 */ if (isFree) {
/* 400 */ returnManagedConnection(cl, false);
/* */ }
/* */
/* 403 */ if (throwable != null)
/* 404 */ JBossResourceException.rethrowAsResourceException("Could not delist resource, probably a transaction rollback? ", throwable);
/* */ }
/* */
/* */ public ConnectionListener createConnectionListener(ManagedConnection mc, Object context)
/* */ throws ResourceException
/* */ {
/* 410 */ XAResource xaResource = null;
/* */
/* 412 */ if (this.localTransactions)
/* */ {
/* 414 */ xaResource = new LocalXAResource(this.log);
/* */
/* 416 */ if (this.xaResourceTimeout != 0) {
/* 417 */ this.log.debug("XAResource transaction timeout cannot be set for local transactions: " + getJndiName());
/* */ }
/* */
/* */ }
/* */ else
/* */ {
/* 423 */ if (this.wrapXAResource)
/* */ {
/* 425 */ this.log.trace("Generating XAResourceWrapper for TxConnectionManager" + this);
/* 426 */ xaResource = new XAResourceWrapper(this.isSameRMOverrideValue, this.padXid, mc.getXAResource());
/* */ }
/* */ else
/* */ {
/* 432 */ this.log.trace("Not wrapping XAResource.");
/* 433 */ xaResource = mc.getXAResource();
/* */ }
/* */
/* 437 */ if (this.xaResourceTimeout != 0)
/* */ {
/* */ try
/* */ {
/* 441 */ if (!xaResource.setTransactionTimeout(this.xaResourceTimeout))
/* 442 */ this.log.debug("XAResource does not support transaction timeout configuration: " + getJndiName());
/* */ }
/* */ catch (XAException e)
/* */ {
/* 446 */ throw new JBossResourceException("Unable to set XAResource transaction timeout: " + getJndiName(), e);
/* */ }
/* */ }
/* */ }
/* */
/* 451 */ ConnectionListener cli = new TxConnectionEventListener(mc, this.poolingStrategy, context, this.log, xaResource);
/* 452 */ mc.addConnectionEventListener(cli);
/* 453 */ return cli;
/* */ }
/* */
/* */ public boolean isTransactional()
/* */ {
/* 458 */ return !TxUtils.isCompleted(this.tm);
/* */ }
/* */
/* */ private class LocalXAResource
/* */ implements XAResource, LastResource
/* */ {
/* */ protected Logger log;
/* */ private ConnectionListener cl;
/* 917 */ private boolean warned = false;
/* */ private Xid currentXid;
/* */
/* */ public LocalXAResource(Logger log)
/* */ {
/* 923 */ this.log = log;
/* */ }
/* */
/* */ void setConnectionListener(ConnectionListener cl)
/* */ {
/* 928 */ this.cl = cl;
/* */ }
/* */
/* */ public void start(Xid xid, int flags)
/* */ throws XAException
/* */ {
/* 935 */ if (TxConnectionManager.this.trace)
/* 936 */ this.log.trace("start, xid: " + xid + ", flags: " + flags);
/* 937 */ if ((this.currentXid != null) && (flags == 0))
/* 938 */ throw new JBossLocalXAException("Trying to start a new tx when old is not complete! old: " + this.currentXid + ", new " + xid + ", flags " + flags, -6);
/* 939 */ if ((this.currentXid == null) && (flags != 0))
/* 940 */ throw new JBossLocalXAException("Trying to start a new tx with wrong flags! new " + xid + ", flags " + flags, -6);
/* 941 */ if (this.currentXid == null)
/* */ {
/* */ try
/* */ {
/* 945 */ this.cl.getManagedConnection().getLocalTransaction().begin();
/* */ }
/* */ catch (ResourceException re)
/* */ {
/* 949 */ throw new JBossLocalXAException("Error trying to start local tx: ", -3, re);
/* */ }
/* */ catch (Throwable t)
/* */ {
/* 953 */ throw new JBossLocalXAException("Throwable trying to start local transaction!", -3, t);
/* */ }
/* */
/* 956 */ this.currentXid = xid;
/* */ }
/* */ }
/* */
/* */ public void end(Xid xid, int flags) throws XAException
/* */ {
/* 962 */ if (TxConnectionManager.this.trace)
/* 963 */ this.log.trace("end on xid: " + xid + " called with flags " + flags);
/* */ }
/* */
/* */ public void commit(Xid xid, boolean onePhase) throws XAException
/* */ {
/* 968 */ if (!xid.equals(this.currentXid))
/* 969 */ throw new JBossLocalXAException("wrong xid in commit: expected: " + this.currentXid + ", got: " + xid, -6);
/* 970 */ this.currentXid = null;
/* */ try
/* */ {
/* 973 */ this.cl.getManagedConnection().getLocalTransaction().commit();
/* */ }
/* */ catch (ResourceException re)
/* */ {
/* 977 */ TxConnectionManager.this.returnManagedConnection(this.cl, true);
/* 978 */ if (TxConnectionManager.this.trace)
/* 979 */ this.log.trace("commit problem: ", re);
/* 980 */ throw new JBossLocalXAException("could not commit local tx", 100, re);
/* */ }
/* */ }
/* */
/* */ public void forget(Xid xid) throws XAException
/* */ {
/* 986 */ throw new JBossLocalXAException("forget not supported in local tx", -3);
/* */ }
/* */
/* */ public int getTransactionTimeout()
/* */ throws XAException
/* */ {
/* 992 */ return 0;
/* */ }
/* */
/* */ public boolean isSameRM(XAResource xaResource) throws XAException
/* */ {
/* 997 */ return xaResource == this;
/* */ }
/* */
/* */ public int prepare(Xid xid) throws XAException
/* */ {
/* 1002 */ if (!this.warned)
/* 1003 */ this.log.warn("Prepare called on a local tx. Use of local transactions on a jta transaction with more than one branch may result in inconsistent data in some cases of failure.");
/* 1004 */ this.warned = true;
/* 1005 */ return 0;
/* */ }
/* */
/* */ public Xid[] recover(int flag) throws XAException
/* */ {
/* 1010 */ throw new JBossLocalXAException("no recover with local-tx only resource managers", -3);
/* */ }
/* */
/* */ public void rollback(Xid xid) throws XAException
/* */ {
/* 1015 */ if (!xid.equals(this.currentXid))
/* 1016 */ throw new JBossLocalXAException("wrong xid in rollback: expected: " + this.currentXid + ", got: " + xid, -6);
/* 1017 */ this.currentXid = null;
/* */ try
/* */ {
/* 1020 */ this.cl.getManagedConnection().getLocalTransaction().rollback();
/* */ }
/* */ catch (ResourceException re)
/* */ {
/* 1024 */ TxConnectionManager.this.returnManagedConnection(this.cl, true);
/* 1025 */ if (TxConnectionManager.this.trace)
/* 1026 */ this.log.trace("rollback problem: ", re);
/* 1027 */ throw new JBossLocalXAException("could not rollback local tx", -3, re);
/* */ }
/* */ }
/* */
/* */ public boolean setTransactionTimeout(int seconds)
/* */ throws XAException
/* */ {
/* 1034 */ return false;
/* */ }
/* */ }
/* */
/* */ protected class TxConnectionEventListener extends BaseConnectionManager2.BaseConnectionEventListener
/* */ {
/* */ protected Logger log;
/* */ protected TransactionSynchronization transactionSynchronization;
/* */ private final XAResource xaResource;
/* 474 */ private SynchronizedBoolean localTransaction = new SynchronizedBoolean(false);
/* */
/* */ public TxConnectionEventListener(ManagedConnection mc, ManagedConnectionPool mcp, Object context, Logger log, XAResource xaResource) throws ResourceException
/* */ {
/* 478 */ super(mc, mcp, context, log);
/* 479 */ this.log = log;
/* 480 */ this.xaResource = xaResource;
/* */
/* 482 */ if ((xaResource instanceof TxConnectionManager.LocalXAResource))
/* 483 */ ((TxConnectionManager.LocalXAResource)xaResource).setConnectionListener(this);
/* */ }
/* */
/* */ public void enlist()
/* */ throws SystemException
/* */ {
/* 523 */ int status = TxConnectionManager.this.tm.getStatus();
/* 524 */ if (status == 6)
/* */ {
/* 526 */ if ((this.transactionSynchronization != null) && (this.transactionSynchronization.currentTx != null))
/* */ {
/* 528 */ String error = "Attempt to use connection outside a transaction when already a tx!";
/* 529 */ if (this.trace)
/* 530 */ this.log.trace(error + " " + this);
/* 531 */ throw new IllegalStateException(error);
/* */ }
/* 533 */ if (this.trace)
/* 534 */ this.log.trace("No transaction, no need to enlist: " + this);
/* 535 */ return;
/* */ }
/* */
/* 539 */ Transaction threadTx = TxConnectionManager.this.tm.getTransaction();
/* 540 */ if ((threadTx == null) || (status != 0))
/* */ {
/* 542 */ String error = "Transaction " + threadTx + " is not active " + TxUtils.getStatusAsString(status);
/* 543 */ if (this.trace)
/* 544 */ this.log.trace(error + " cl=" + this);
/* 545 */ throw new IllegalStateException(error);
/* */ }
/* */
/* 548 */ if (this.trace) {
/* 549 */ this.log.trace("Pre-enlist: " + this + " threadTx=" + threadTx);
/* */ }
/* */
/* 552 */ TransactionSynchronization ourSynchronization = null;
/* */
/* 556 */ TransactionSynchronizer synchronizer = null;
/* */
/* 558 */ TransactionSynchronizer.lock(threadTx);
/* */ try
/* */ {
/* 563 */ if ((!isTrackByTx()) && (this.transactionSynchronization != null))
/* */ {
/* 565 */ String error = "Can't enlist - already a tx!";
/* 566 */ if (this.trace)
/* 567 */ this.log.trace(error + " " + this);
/* 568 */ throw new IllegalStateException(error);
/* */ }
/* */
/* 572 */ if ((this.transactionSynchronization != null) && (!this.transactionSynchronization.currentTx.equals(threadTx)))
/* */ {
/* 574 */ String error = "Trying to change transaction " + threadTx + " in enlist!";
/* 575 */ if (this.trace)
/* 576 */ this.log.trace(error + " " + this);
/* 577 */ throw new IllegalStateException(error);
/* */ }
/* */
/* */ try
/* */ {
/* 583 */ if (this.trace)
/* 584 */ this.log.trace("Get synchronizer " + this + " threadTx=" + threadTx);
/* 585 */ synchronizer = TransactionSynchronizer.getRegisteredSynchronizer(threadTx);
/* */ }
/* */ catch (Throwable t)
/* */ {
/* 589 */ setTrackByTx(false);
/* 590 */ TxConnectionManager.rethrowAsSystemException("Cannot register synchronization", threadTx, t);
/* */ }
/* */
/* 594 */ if (this.transactionSynchronization == null)
/* */ {
/* 596 */ TransactionSynchronization synchronization = new TransactionSynchronization(threadTx, isTrackByTx());
/* 597 */ synchronizer.addUnenlisted(synchronization);
/* 598 */ this.transactionSynchronization = synchronization;
/* */ }
/* 600 */ ourSynchronization = this.transactionSynchronization;
/* */ }
/* */ finally
/* */ {
/* 604 */ TransactionSynchronizer.unlock(threadTx);
/* */ }
/* */
/* 608 */ ArrayList unenlisted = synchronizer.getUnenlisted();
/* 609 */ if (unenlisted != null)
/* */ {
/* */ try
/* */ {
/* 613 */ for (int i = 0; i < unenlisted.size(); i++)
/* */ {
/* 615 */ TransactionSynchronization sync = (TransactionSynchronization)unenlisted.get(i);
/* 616 */ if (sync.enlist())
/* 617 */ synchronizer.addEnlisted(sync);
/* */ }
/* */ }
/* */ finally
/* */ {
/* 622 */ synchronizer.enlisted();
/* */ }
/* */
/* */ }
/* */
/* 627 */ if (this.trace)
/* 628 */ this.log.trace("Check enlisted " + this + " threadTx=" + threadTx);
/* 629 */ ourSynchronization.checkEnlisted();
/* */ }
/* */
/* */ public void delist() throws ResourceException
/* */ {
/* 634 */ if (this.trace) {
/* 635 */ this.log.trace("delisting " + this);
/* */ }
/* */ try
/* */ {
/* 639 */ if ((!isTrackByTx()) && (this.transactionSynchronization != null))
/* */ {
/* 641 */ Transaction tx = this.transactionSynchronization.currentTx;
/* 642 */ TransactionSynchronization synchronization = this.transactionSynchronization;
/* 643 */ this.transactionSynchronization = null;
/* 644 */ if (TxUtils.isUncommitted(tx))
/* */ {
/* 646 */ TransactionSynchronizer synchronizer = TransactionSynchronizer.getRegisteredSynchronizer(tx);
/* 647 */ if (synchronization.enlisted)
/* 648 */ synchronizer.removeEnlisted(synchronization);
/* 649 */ if (!tx.delistResource(getXAResource(), 33554432))
/* 650 */ throw new ResourceException("Failure to delist resource: " + this);
/* */ }
/* */ }
/* */ }
/* */ catch (Throwable t)
/* */ {
/* 656 */ JBossResourceException.rethrowAsResourceException("Error in delist!", t);
/* */ }
/* */ }
/* */
/* */ protected XAResource getXAResource()
/* */ {
/* 663 */ return this.xaResource;
/* */ }
/* */
/* */ public void connectionClosed(ConnectionEvent ce)
/* */ {
/* 668 */ if (this.trace)
/* 669 */ this.log.trace("connectionClosed called mc=" + getManagedConnection());
/* 670 */ if (getManagedConnection() != (ManagedConnection)ce.getSource())
/* 671 */ throw new IllegalArgumentException("ConnectionClosed event received from wrong ManagedConnection! Expected: " + getManagedConnection() + ", actual: " + ce.getSource());
/* */ try
/* */ {
/* 674 */ TxConnectionManager.this.getCcm().unregisterConnection(TxConnectionManager.this, ce.getConnectionHandle());
/* */ }
/* */ catch (Throwable t)
/* */ {
/* 678 */ this.log.info("throwable from unregister connection", t);
/* */ }
/* */
/* */ try
/* */ {
/* 683 */ TxConnectionManager.this.unregisterAssociation(this, ce.getConnectionHandle());
/* 684 */ boolean isFree = isManagedConnectionFree();
/* 685 */ if (this.trace) {
/* 686 */ this.log.trace("isManagedConnectionFree=" + isFree + " mc=" + getManagedConnection());
/* */ }
/* 688 */ if (isFree)
/* */ {
/* 690 */ delist();
/* 691 */ TxConnectionManager.this.returnManagedConnection(this, false);
/* */ }
/* */ }
/* */ catch (Throwable t)
/* */ {
/* 696 */ this.log.error("Error while closing connection handle!", t);
/* 697 */ TxConnectionManager.this.returnManagedConnection(this, true);
/* */ }
/* */ }
/* */
/* */ public void localTransactionStarted(ConnectionEvent ce)
/* */ {
/* 703 */ this.localTransaction.set(true);
/* */ }
/* */
/* */ public void localTransactionCommitted(ConnectionEvent ce)
/* */ {
/* 708 */ this.localTransaction.set(false);
/* */ }
/* */
/* */ public void localTransactionRolledback(ConnectionEvent ce)
/* */ {
/* 713 */ this.localTransaction.set(false);
/* */ }
/* */
/* */ public void tidyup()
/* */ throws ResourceException
/* */ {
/* 719 */ if (this.localTransaction.get())
/* */ {
/* 721 */ LocalTransaction local = null;
/* 722 */ ManagedConnection mc = getManagedConnection();
/* */ try
/* */ {
/* 725 */ local = mc.getLocalTransaction();
/* */ }
/* */ catch (Throwable t)
/* */ {
/* 729 */ JBossResourceException.rethrowAsResourceException("Unfinished local transaction - error getting local transaction from " + this, t);
/* */ }
/* 731 */ if (local == null) {
/* 732 */ throw new ResourceException("Unfinished local transaction but managed connection does not provide a local transaction. " + this);
/* */ }
/* */
/* 735 */ local.rollback();
/* 736 */ this.log.debug("Unfinished local transaction was rolled back." + this);
/* */ }
/* */ }
/* */
/* */ public void connectionErrorOccurred(ConnectionEvent ce)
/* */ {
/* 743 */ this.transactionSynchronization = null;
/* 744 */ super.connectionErrorOccurred(ce);
/* */ }
/* */
/* */ public boolean isManagedConnectionFree()
/* */ {
/* 750 */ if ((isTrackByTx()) && (this.transactionSynchronization != null))
/* 751 */ return false;
/* 752 */ return super.isManagedConnectionFree();
/* */ }
/* */
/* */ protected void toString(StringBuffer buffer)
/* */ {
/* 901 */ buffer.append(" xaResource=").append(this.xaResource);
/* 902 */ buffer.append(" txSync=").append(this.transactionSynchronization);
/* */ }
/* */
/* */ private class TransactionSynchronization
/* */ implements Synchronization
/* */ {
/* */ private Transaction currentTx;
/* */ private boolean wasTrackByTx;
/* 764 */ private boolean enlisted = false;
/* */ private Throwable enlistError;
/* */
/* */ public TransactionSynchronization(Transaction tx, boolean trackByTx)
/* */ {
/* 776 */ this.currentTx = tx;
/* 777 */ this.wasTrackByTx = trackByTx;
/* */ }
/* */
/* */ public void checkEnlisted()
/* */ throws SystemException
/* */ {
/* 787 */ if (this.enlistError != null)
/* */ {
/* 789 */ String error = "Error enlisting resource in transaction=" + this.currentTx;
/* 790 */ if (TxConnectionManager.TxConnectionEventListener.this.trace) {
/* 791 */ TxConnectionManager.TxConnectionEventListener.this.log.trace(error + " " + TxConnectionManager.TxConnectionEventListener.this);
/* */ }
/* */
/* 795 */ if (this.enlistError == TxConnectionManager.FAILED_TO_ENLIST) {
/* 796 */ throw new SystemException(TxConnectionManager.FAILED_TO_ENLIST + " tx=" + this.currentTx);
/* */ }
/* */
/* 799 */ SystemException e = new SystemException(error);
/* 800 */ e.initCause(this.enlistError);
/* 801 */ throw e;
/* */ }
/* */
/* 804 */ if (!this.enlisted)
/* */ {
/* 806 */ String error = "Resource is not enlisted in transaction=" + this.currentTx;
/* 807 */ if (TxConnectionManager.TxConnectionEventListener.this.trace)
/* 808 */ TxConnectionManager.TxConnectionEventListener.this.log.trace(error + " " + TxConnectionManager.TxConnectionEventListener.this);
/* 809 */ throw new IllegalStateException("Resource was not enlisted.");
/* */ }
/* */ }
/* */
/* */ public boolean enlist()
/* */ {
/* 820 */ if (TxConnectionManager.TxConnectionEventListener.this.trace)
/* 821 */ TxConnectionManager.TxConnectionEventListener.this.log.trace("Enlisting resource " + TxConnectionManager.TxConnectionEventListener.this);
/* */ try
/* */ {
/* 824 */ XAResource resource = TxConnectionManager.TxConnectionEventListener.this.getXAResource();
/* 825 */ if (false == this.currentTx.enlistResource(resource))
/* 826 */ this.enlistError = TxConnectionManager.FAILED_TO_ENLIST;
/* */ }
/* */ catch (Throwable t)
/* */ {
/* 830 */ this.enlistError = t;
/* */ }
/* */
/* 833 */ synchronized (this)
/* */ {
/* 835 */ if (this.enlistError != null)
/* */ {
/* 837 */ if (TxConnectionManager.TxConnectionEventListener.this.trace)
/* 838 */ TxConnectionManager.TxConnectionEventListener.this.log.trace("Failed to enlist resource " + TxConnectionManager.TxConnectionEventListener.this, this.enlistError);
/* 839 */ TxConnectionManager.TxConnectionEventListener.this.setTrackByTx(false);
/* 840 */ TxConnectionManager.TxConnectionEventListener.this.transactionSynchronization = null;
/* 841 */ return false;
/* */ }
/* */
/* 844 */ if (TxConnectionManager.TxConnectionEventListener.this.trace)
/* 845 */ TxConnectionManager.TxConnectionEventListener.this.log.trace("Enlisted resource " + TxConnectionManager.TxConnectionEventListener.this);
/* 846 */ this.enlisted = true;
/* 847 */ return true;
/* */ }
/* */ }
/* */
/* */ public void beforeCompletion()
/* */ {
/* */ }
/* */
/* */ public void afterCompletion(int status)
/* */ {
/* 858 */ if (TxConnectionManager.TxConnectionEventListener.this.getState() == 2) {
/* 859 */ return;
/* */ }
/* */
/* 862 */ if (!equals(TxConnectionManager.TxConnectionEventListener.this.transactionSynchronization))
/* */ {
/* 865 */ if (!this.wasTrackByTx) {
/* 866 */ return;
/* */ }
/* */
/* 870 */ String message = "afterCompletion called with wrong tx! Expected: " + this + ", actual: " + TxConnectionManager.TxConnectionEventListener.this.transactionSynchronization;
/* 871 */ IllegalStateException e = new IllegalStateException(message);
/* 872 */ TxConnectionManager.TxConnectionEventListener.this.log.error("There is something wrong with the pooling?", e);
/* */ }
/* */
/* 876 */ TxConnectionManager.TxConnectionEventListener.this.transactionSynchronization = null;
/* */
/* 878 */ if (this.wasTrackByTx)
/* */ {
/* 880 */ TxConnectionManager.TxConnectionEventListener.this.setTrackByTx(false);
/* 881 */ if (TxConnectionManager.TxConnectionEventListener.this.isManagedConnectionFree())
/* 882 */ TxConnectionManager.this.returnManagedConnection(TxConnectionManager.TxConnectionEventListener.this, false);
/* */ }
/* */ }
/* */
/* */ public String toString()
/* */ {
/* 888 */ StringBuffer buffer = new StringBuffer();
/* 889 */ buffer.append("TxSync").append(System.identityHashCode(this));
/* 890 */ buffer.append("{tx=").append(this.currentTx);
/* 891 */ buffer.append(" wasTrackByTx=").append(this.wasTrackByTx);
/* 892 */ buffer.append(" enlisted=").append(this.enlisted);
/* 893 */ buffer.append("}");
/* 894 */ return buffer.toString();
/* */ }
/* */ }
/* */ }
/* */ }
/* Location: /home/mnovotny/projects/EMBEDDED_JBOSS_BETA3_COMMUNITY/embedded/output/lib/embedded-jboss/lib/jboss-embedded-all.jar
* Qualified Name: org.jboss.resource.connectionmanager.TxConnectionManager
* JD-Core Version: 0.6.0
*/