Package com.atomikos.jms

Source Code of com.atomikos.jms.AtomikosPooledJmsConnection

             
/*
* Copyright 2000-2008, Atomikos (http://www.atomikos.com)
*
* This code ("Atomikos TransactionsEssentials"), by itself,
* is being distributed under the
* Apache License, Version 2.0 ("License"), a copy of which may be found at
* http://www.atomikos.com/licenses/apache-license-2.0.txt .
* You may not use this file except in compliance with the License.
*            
* While the License grants certain patent license rights,
* those patent license rights only extend to the use of
* Atomikos TransactionsEssentials by itself.
*            
* This code (Atomikos TransactionsEssentials) contains certain interfaces
* in package (namespace) com.atomikos.icatch
* (including com.atomikos.icatch.Participant) which, if implemented, may
* infringe one or more patents held by Atomikos. 
* It should be appreciated that you may NOT implement such interfaces;
* licensing to implement these interfaces must be obtained separately from Atomikos.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*/
package com.atomikos.jms;

import java.lang.reflect.Proxy;

import javax.jms.JMSException;
import javax.jms.XAConnection;

import com.atomikos.datasource.pool.AbstractXPooledConnection;
import com.atomikos.datasource.pool.ConnectionPoolProperties;
import com.atomikos.datasource.pool.CreateConnectionException;
import com.atomikos.datasource.pool.Reapable;
import com.atomikos.datasource.xa.XATransactionalResource;
import com.atomikos.datasource.xa.session.SessionHandleStateChangeListener;
import com.atomikos.icatch.CompositeTransaction;
import com.atomikos.icatch.CompositeTransactionManager;
import com.atomikos.icatch.HeuristicMessage;
import com.atomikos.icatch.jta.TransactionManagerImp;
import com.atomikos.icatch.system.Configuration;
import com.atomikos.util.DynamicProxy;

class AtomikosPooledJmsConnection extends AbstractXPooledConnection implements SessionHandleStateChangeListener {
 
  private XAConnection xaConnection;
  private XATransactionalResource jmsTransactionalResource;
  private Reapable currentProxy;
  private ConnectionPoolProperties props;
  private boolean erroneous;

  protected AtomikosPooledJmsConnection(XAConnection xac, XATransactionalResource jmsTransactionalResource, ConnectionPoolProperties props) {
    super(props);
    this.jmsTransactionalResource = jmsTransactionalResource;
    this.xaConnection = xac;
    this.props = props;
    this.erroneous = false;
  }

  protected Reapable doCreateConnectionProxy(HeuristicMessage msg) throws CreateConnectionException {
    currentProxy = AtomikosJmsConnectionProxy.newInstance ( xaConnection , jmsTransactionalResource , this , props );
    return currentProxy;
  }

  protected void testUnderlyingConnection() throws CreateConnectionException {
    if ( isErroneous() ) throw new CreateConnectionException ( this + ": connection is erroneous" );
  }

  public void destroy() {
    Configuration.logDebug ( this + ": destroying connection..." );
    if (xaConnection != null) {
      try {
        xaConnection.close();
      } catch (JMSException ex) {
        //ignore but log
        Configuration.logWarning ( this + ": error closing XAConnection: " , ex );
      }
    }
    xaConnection = null;
  }

  public synchronized boolean isAvailable() {
    boolean ret = true;
    if ( currentProxy != null ) {
      DynamicProxy dproxy = ( DynamicProxy ) currentProxy;
      AtomikosJmsConnectionProxy proxy = (AtomikosJmsConnectionProxy) dproxy.getInvocationHandler();     
      ret = proxy.isAvailable();
    }
    return ret;
  }
 

  public synchronized boolean isErroneous() {
    boolean ret = erroneous;
    if ( currentProxy != null ) {
      AtomikosJmsConnectionProxy proxy = (AtomikosJmsConnectionProxy) Proxy.getInvocationHandler ( currentProxy );
      ret = ret || proxy.isErroneous();
    }
    return ret;
  }

  public synchronized boolean isInTransaction ( CompositeTransaction ct ) {
    boolean ret = false;
    if ( currentProxy != null ) {
      DynamicProxy dproxy = ( DynamicProxy ) currentProxy;
      AtomikosJmsConnectionProxy proxy = (AtomikosJmsConnectionProxy) dproxy.getInvocationHandler();
      ret = proxy.isInTransaction ( ct );
    }
    return ret;
  }

  public void onTerminated() {
    boolean fireTerminatedEvent = false;
   
    synchronized ( this ) {
      //a session has terminated -> check reusability of all remaining
      Configuration.logDebug ( this + ": a session has terminated, is connection now available ? " + isAvailable() );
      if ( isAvailable() ) {
        if ( currentProxy != null ) {
          DynamicProxy dproxy = ( DynamicProxy ) currentProxy;
          AtomikosJmsConnectionProxy proxy = (AtomikosJmsConnectionProxy) dproxy.getInvocationHandler();
          if ( proxy.isErroneous() ) erroneous = true;
          proxy.destroy();
        }
       
        fireTerminatedEvent = true;
      } else {
        //not yet available, but check if the connection is erroneous
        //which happens if the session being terminated is erroneous
        if ( currentProxy != null ) {
          DynamicProxy dproxy = ( DynamicProxy ) currentProxy;
          AtomikosJmsConnectionProxy proxy = (AtomikosJmsConnectionProxy) dproxy.getInvocationHandler();
          if ( proxy.isErroneous() ) erroneous = true;
        }
      }
    }
   
        if ( fireTerminatedEvent ) {
            //callbacks done outside synch to avoid deadlock in case 27614
          fireOnXPooledConnectionTerminated();
        }

   
  }
 
  public boolean canBeRecycledForCallingThread ()
  {
    boolean ret = false;
    if ( currentProxy != null ) {
      CompositeTransactionManager tm = Configuration.getCompositeTransactionManager();
     
      CompositeTransaction current = tm.getCompositeTransaction();
      if ( ( current != null ) && ( current.getProperty ( TransactionManagerImp.JTA_PROPERTY_NAME) != null )) {
        DynamicProxy dproxy = ( DynamicProxy ) currentProxy;
        AtomikosJmsConnectionProxy proxy = (AtomikosJmsConnectionProxy) dproxy.getInvocationHandler();
        //recycle if either inactive in this tx, OR if active (since a new session will be created anyway, and
        //concurrent sessions are allowed on the same underlying connection!
        ret = proxy.isInactiveInTransaction(current) || proxy.isInTransaction( current );
      }
    }
   
   
    return ret;
  }
 
  public String toString()
  {
    return "atomikos pooled connection for resource " + jmsTransactionalResource.getName();
  }

}
TOP

Related Classes of com.atomikos.jms.AtomikosPooledJmsConnection

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.