Search in sources :

Example 1 with JavaEETransaction

use of com.sun.enterprise.transaction.api.JavaEETransaction in project Payara by payara.

the class EJBContainerTransactionManager method useClientTx.

/**
 * Use caller transaction to execute a bean method
 */
protected void useClientTx(Transaction prevTx, EjbInvocation inv) {
    Transaction clientTx;
    int status = -1;
    int prevStatus = -1;
    try {
        // Note: inv.clientTx will not be set at this point.
        clientTx = transactionManager.getTransaction();
        // clientTx cant be null
        status = clientTx.getStatus();
        if (prevTx != null) {
            prevStatus = prevTx.getStatus();
        }
    } catch (Exception ex) {
        try {
            transactionManager.setRollbackOnly();
        } catch (Exception e) {
            // FIXME: Use LogStrings.properties
            _logger.log(Level.FINEST, "", e);
        }
        throw new TransactionRolledbackLocalException("", ex);
    }
    // to invoke the EJB, so throw an exception back to client.
    if (status == Status.STATUS_MARKED_ROLLBACK || status == Status.STATUS_ROLLEDBACK || status == Status.STATUS_ROLLING_BACK) {
        throw new TransactionRolledbackLocalException("Client's transaction aborted");
    }
    container.validateEMForClientTx(inv, (JavaEETransaction) clientTx);
    if (prevTx == null || prevStatus == Status.STATUS_NO_TRANSACTION) {
        // First time the bean is running in this new client Tx
        EJBContextImpl context = (EJBContextImpl) inv.context;
        // Must change this for singleton
        if (!container.isSingleton) {
            context.setTransaction(clientTx);
        }
        try {
            transactionManager.enlistComponentResources();
            if (!container.isStatelessSession && !container.isMessageDriven && !container.isSingleton) {
                // Register sync for methods other than finders/home methods
                if (!inv.invocationInfo.isHomeFinder) {
                    ejbContainerUtilImpl.getContainerSync(clientTx).addBean(context);
                }
                container.afterBegin(context);
            }
        } catch (Exception ex) {
            try {
                transactionManager.setRollbackOnly();
            } catch (Exception e) {
                // FIXME: Use LogStrings.properties
                _logger.log(Level.FINEST, "", e);
            }
            throw new TransactionRolledbackLocalException("", ex);
        }
    } else {
        // Bean already has a transaction associated with it.
        if (!prevTx.equals(clientTx)) {
            // EntityBeans will get a different context for every Tx.
            if (container.isSession) {
                // Row 2 in Table E
                throw new IllegalStateException("EJB is already associated with an incomplete transaction");
            }
        } else {
            // with the transaction
            try {
                transactionManager.enlistComponentResources();
            } catch (Exception ex) {
                try {
                    transactionManager.setRollbackOnly();
                } catch (Exception e) {
                    // FIXME: Use LogStrings.properties
                    _logger.log(Level.FINEST, "", e);
                }
                throw new TransactionRolledbackLocalException("", ex);
            }
        }
    }
}
Also used : TransactionRolledbackLocalException(javax.ejb.TransactionRolledbackLocalException) Transaction(javax.transaction.Transaction) UserTransaction(javax.transaction.UserTransaction) JavaEETransaction(com.sun.enterprise.transaction.api.JavaEETransaction) ContainerTransaction(org.glassfish.ejb.deployment.descriptor.ContainerTransaction) TransactionRolledbackLocalException(javax.ejb.TransactionRolledbackLocalException) TransactionRequiredLocalException(javax.ejb.TransactionRequiredLocalException) EJBException(javax.ejb.EJBException) SystemException(javax.transaction.SystemException) RollbackException(javax.transaction.RollbackException) NoSuchObjectLocalException(javax.ejb.NoSuchObjectLocalException) NoSuchEntityException(javax.ejb.NoSuchEntityException)

Example 2 with JavaEETransaction

use of com.sun.enterprise.transaction.api.JavaEETransaction in project Payara by payara.

the class ActiveTxCache method addIncompleteTxEJB.

/**
 * Called only from afterBegin.
 * This EJB is invoked either with client's tx (in which case
 * it would already be in table), or with new tx (in which case
 * it would not be in table).
 */
private void addIncompleteTxEJB(EntityContextImpl context) {
    JavaEETransaction current = (JavaEETransaction) context.getTransaction();
    if (current == null) {
        return;
    }
    if ((containerStateManager.isNullEJBObject(context)) && (containerStateManager.isNullEJBLocalObject(context))) {
        return;
    }
    // Its ok to add this context without checking if its already there.
    ActiveTxCache activeTxCache = (ActiveTxCache) ejbContainerUtilImpl.getActiveTxCache(current);
    if (activeTxCache == null) {
        activeTxCache = new ActiveTxCache(DEFAULT_TX_CACHE_BUCKETS);
        ejbContainerUtilImpl.setActiveTxCache(current, activeTxCache);
    }
    activeTxCache.add(context);
    Vector beans = ejbContainerUtilImpl.getBeans(current);
    beans.add(context);
}
Also used : JavaEETransaction(com.sun.enterprise.transaction.api.JavaEETransaction) Vector(java.util.Vector)

Example 3 with JavaEETransaction

use of com.sun.enterprise.transaction.api.JavaEETransaction in project Payara by payara.

the class ActiveTxCache method getEJBWithIncompleteTx.

// getReadyEJB(inv)
// called from releaseContext, afterCompletion
/**
 * Get an EJB instance for this EJBObject and current client Tx
 * Called only from getContext.
 * Return null if there no INCOMPLETE_TX bean for the pkey & tx.
 */
private EntityContextImpl getEJBWithIncompleteTx(EjbInvocation inv) {
    // We need to make sure that two concurrent client
    // invocations with same primary key and same client tx
    // get the SAME EJB instance.
    // So we need to maintain exactly one copy of an EJB's state
    // per transaction.
    JavaEETransaction current = null;
    try {
        current = (JavaEETransaction) transactionManager.getTransaction();
    } catch (SystemException ex) {
        throw new EJBException(ex);
    }
    EntityContextImpl ctx = null;
    if (current != null) {
        ActiveTxCache activeTxCache = (ActiveTxCache) ejbContainerUtilImpl.getActiveTxCache(current);
        ctx = (activeTxCache == null) ? null : activeTxCache.get(this, getInvocationKey(inv));
        inv.foundInTxCache = (ctx != null);
    }
    return ctx;
}
Also used : JavaEETransaction(com.sun.enterprise.transaction.api.JavaEETransaction) SystemException(javax.transaction.SystemException) EJBException(javax.ejb.EJBException)

Example 4 with JavaEETransaction

use of com.sun.enterprise.transaction.api.JavaEETransaction in project Payara by payara.

the class ConnectionPool method getResourceFromTransaction.

/**
 * Try to get a resource from current transaction if it is shareable<br>
 * @param tran Current Transaction
 * @param alloc ResourceAllocator
 * @param spec ResourceSpec
 * @return result ResourceHandle
 */
private ResourceHandle getResourceFromTransaction(Transaction tran, ResourceAllocator alloc, ResourceSpec spec) {
    ResourceHandle result = null;
    try {
        // shareable, so abort right here if that's not the case
        if (tran != null && alloc.shareableWithinComponent()) {
            // TODO should be handled by PoolTxHelper
            JavaEETransaction j2eetran = (JavaEETransaction) tran;
            // case 1. look for free and enlisted in same tx
            Set set = j2eetran.getResources(poolInfo);
            if (set != null) {
                Iterator iter = set.iterator();
                while (iter.hasNext()) {
                    ResourceHandle h = (ResourceHandle) iter.next();
                    if (h.hasConnectionErrorOccurred()) {
                        iter.remove();
                        continue;
                    }
                    ResourceState state = h.getResourceState();
                    /*
                         * One can share a resource only for the following conditions:
                         * 1. The caller resource is shareable (look at the outermost
                         *    if marked comment-1
                         * 2. The resource enlisted inside the transaction is shareable
                         * 3. We are dealing with XA resources OR
                         *    We are dealing with a non-XA resource that's not in use
                         *    Note that sharing a non-xa resource that's in use involves
                         *    associating physical connections.
                         * 4. The credentials of the resources match
                         */
                    if (h.getResourceAllocator().shareableWithinComponent()) {
                        if (spec.isXA() || poolTxHelper.isNonXAResourceAndFree(j2eetran, h)) {
                            if (matchConnections) {
                                if (!alloc.matchConnection(h)) {
                                    if (poolLifeCycleListener != null) {
                                        poolLifeCycleListener.connectionNotMatched();
                                    }
                                    continue;
                                }
                                if (h.hasConnectionErrorOccurred()) {
                                    if (failAllConnections) {
                                        // if failAllConnections has happened, we flushed the
                                        // pool, so we don't have to do iter.remove else we
                                        // will get a ConncurrentModificationException
                                        result = null;
                                        break;
                                    }
                                    iter.remove();
                                    continue;
                                }
                                if (poolLifeCycleListener != null) {
                                    poolLifeCycleListener.connectionMatched();
                                }
                            }
                            if (state.isFree())
                                setResourceStateToBusy(h);
                            result = h;
                            break;
                        }
                    }
                }
            }
        }
    } catch (ClassCastException e) {
        if (_logger.isLoggable(Level.FINE)) {
            _logger.log(Level.FINE, "Pool: getResource : " + "transaction is not JavaEETransaction but a " + tran.getClass().getName(), e);
        }
    }
    return result;
}
Also used : JavaEETransaction(com.sun.enterprise.transaction.api.JavaEETransaction) ResourceHandle(com.sun.enterprise.resource.ResourceHandle) ResourceState(com.sun.enterprise.resource.ResourceState)

Example 5 with JavaEETransaction

use of com.sun.enterprise.transaction.api.JavaEETransaction in project Payara by payara.

the class ConnectionPool method getResource.

/**
 * returns resource from the pool.
 *
 * @return a free pooled resource object matching the ResourceSpec
 * @throws PoolingException - if any error occurrs
 *                          - or the pool has reached its max size and the
 *                          max-connection-wait-time-in-millis has expired.
 */
public ResourceHandle getResource(ResourceSpec spec, ResourceAllocator alloc, Transaction txn) throws PoolingException, RetryableUnavailableException {
    // Note: this method should not be synchronized or the
    // startTime would be incorrect for threads waiting to enter
    /*
        * Here are all the comments for the method put together for
        * easy reference.
        *  1.
           // - Try to get a free resource. Note: internalGetResource()
           // will create a new resource if none is free and the max has
           // not been reached.
           // - If can't get one, get on the wait queue.
           // - Repeat this until maxWaitTime expires.
           // - If maxWaitTime == 0, repeat indefinitely.

           2.
           //the doFailAllConnectionsProcessing method would already
           //have been invoked by now.
           //We simply go ahead and create a new resource here
           //from the allocator that we have and adjust the resources
           //list accordingly so as to not exceed the maxPoolSize ever
           //(i.e if steadyPoolSize == maxPoolSize )
           ///Also since we are creating the resource out of the allocator
           //that we came into this method with, we need not worry about
           //matching
        */
    ResourceHandle result = null;
    long startTime = System.currentTimeMillis();
    long elapsedWaitTime;
    long remainingWaitTime = 0;
    while (true) {
        if (gateway.allowed()) {
            // See comment #1 above
            JavaEETransaction jtx = ((JavaEETransaction) txn);
            Set resourcesSet = null;
            if (jtx != null) {
                resourcesSet = jtx.getResources(poolInfo);
            }
            // already obtained in the current transaction.
            if (!blocked || (resourcesSet != null && resourcesSet.size() > 0)) {
                try {
                    result = internalGetResource(spec, alloc, txn);
                } finally {
                    gateway.acquiredResource();
                }
            }
        }
        if (result != null) {
            // got one, return it
            if (poolLifeCycleListener != null) {
                poolLifeCycleListener.connectionAcquired(result.getId());
                elapsedWaitTime = System.currentTimeMillis() - startTime;
                poolLifeCycleListener.connectionRequestServed(elapsedWaitTime);
                if (_logger.isLoggable(Level.FINE)) {
                    _logger.log(Level.FINE, "Resource Pool: elapsed time " + "(ms) to get connection for [" + spec + "] : " + elapsedWaitTime);
                }
            }
            // return it
            break;
        } else {
            // did not get a resource.
            if (maxWaitTime > 0) {
                elapsedWaitTime = System.currentTimeMillis() - startTime;
                if (elapsedWaitTime < maxWaitTime) {
                    // time has not expired, determine remaining wait time.
                    remainingWaitTime = maxWaitTime - elapsedWaitTime;
                } else {
                    if (!blocked) {
                        // wait time has expired
                        if (poolLifeCycleListener != null) {
                            poolLifeCycleListener.connectionTimedOut();
                        }
                        String msg = localStrings.getStringWithDefault("poolmgr.no.available.resource", "No available resource. Wait-time expired.");
                        throw new PoolingException(msg);
                    }
                }
            }
            if (!blocked) {
                // add to wait-queue
                Object waitMonitor = new Object();
                if (poolLifeCycleListener != null) {
                    poolLifeCycleListener.connectionRequestQueued();
                }
                synchronized (waitMonitor) {
                    waitQueue.addToQueue(waitMonitor);
                    try {
                        logFine("Resource Pool: getting on wait queue");
                        waitMonitor.wait(remainingWaitTime);
                    } catch (InterruptedException ex) {
                        // Could be system shutdown.
                        break;
                    }
                    // so the overhead for removing inexistant objects is low.
                    if (_logger.isLoggable(Level.FINE)) {
                        _logger.log(Level.FINE, "removing wait monitor from queue: " + waitMonitor);
                    }
                    if (waitQueue.removeFromQueue(waitMonitor)) {
                        if (poolLifeCycleListener != null) {
                            poolLifeCycleListener.connectionRequestDequeued();
                        }
                    }
                }
            } else {
                // add to reconfig-wait-queue
                Object reconfigWaitMonitor = new Object();
                synchronized (reconfigWaitMonitor) {
                    reconfigWaitQueue.addToQueue(reconfigWaitMonitor);
                    try {
                        if (reconfigWaitTime > 0) {
                            if (_logger.isLoggable(Level.FINEST)) {
                                _logger.finest("[DRC] getting into reconfig wait queue for time [" + reconfigWaitTime + "]");
                            }
                            reconfigWaitMonitor.wait(reconfigWaitTime);
                        }
                    } catch (InterruptedException ex) {
                        // Could be system shutdown.
                        break;
                    }
                    // so the overhead for removing inexistent objects is low.
                    if (_logger.isLoggable(Level.FINEST)) {
                        _logger.log(Level.FINEST, "[DRC] removing wait monitor from reconfig-wait-queue: " + reconfigWaitMonitor);
                    }
                    reconfigWaitQueue.removeFromQueue(reconfigWaitMonitor);
                    if (_logger.isLoggable(Level.FINEST)) {
                        _logger.log(Level.FINEST, "[DRC] throwing Retryable-Unavailable-Exception");
                    }
                    RetryableUnavailableException rue = new RetryableUnavailableException("Pool Reconfigured, " + "Connection Factory can retry the lookup");
                    rue.setErrorCode(BadConnectionEventListener.POOL_RECONFIGURED_ERROR_CODE);
                    throw rue;
                }
            }
        }
    }
    alloc.fillInResourceObjects(result);
    return result;
}
Also used : PoolingException(com.sun.appserv.connectors.internal.api.PoolingException) JavaEETransaction(com.sun.enterprise.transaction.api.JavaEETransaction) RetryableUnavailableException(javax.resource.spi.RetryableUnavailableException) ResourceHandle(com.sun.enterprise.resource.ResourceHandle)

Aggregations

JavaEETransaction (com.sun.enterprise.transaction.api.JavaEETransaction)29 SystemException (javax.transaction.SystemException)5 ResourceHandle (com.sun.enterprise.resource.ResourceHandle)4 XAException (javax.transaction.xa.XAException)4 PoolingException (com.sun.appserv.connectors.internal.api.PoolingException)3 ResourceState (com.sun.enterprise.resource.ResourceState)3 RemoteException (java.rmi.RemoteException)3 Vector (java.util.Vector)3 EJBException (javax.ejb.EJBException)3 WorkException (javax.resource.spi.work.WorkException)3 InvocationException (org.glassfish.api.invocation.InvocationException)3 PhysicalEntityManagerWrapper (com.sun.enterprise.container.common.impl.PhysicalEntityManagerWrapper)2 JavaEETransactionManager (com.sun.enterprise.transaction.api.JavaEETransactionManager)2 RequestTraceSpanLog (fish.payara.notification.requesttracing.RequestTraceSpanLog)2 HashMap (java.util.HashMap)2 Map (java.util.Map)2 EntityManagerFactory (javax.persistence.EntityManagerFactory)2 ComponentInvocation (org.glassfish.api.invocation.ComponentInvocation)2 EJBLocalObjectImpl (com.sun.ejb.containers.EJBLocalObjectImpl)1 JavaEEContainer (com.sun.enterprise.container.common.spi.JavaEEContainer)1