Search in sources :

Example 1 with AccessTimeoutDetails

use of org.jboss.as.ejb3.concurrency.AccessTimeoutDetails in project wildfly by wildfly.

the class StatefulSessionComponent method getAccessTimeout.

/**
     * Returns the {@link javax.ejb.AccessTimeout} applicable to given method
     */
public AccessTimeoutDetails getAccessTimeout(Method method) {
    final EJBBusinessMethod ejbMethod = new EJBBusinessMethod(method);
    final AccessTimeoutDetails accessTimeout = this.methodAccessTimeouts.get(ejbMethod);
    if (accessTimeout != null) {
        return accessTimeout;
    }
    // check bean level access timeout
    final AccessTimeoutDetails timeout = this.beanLevelAccessTimeout.get(method.getDeclaringClass().getName());
    if (timeout != null) {
        return timeout;
    }
    return defaultAccessTimeoutProvider.getDefaultAccessTimeout();
}
Also used : EJBBusinessMethod(org.jboss.as.ejb3.component.EJBBusinessMethod) AccessTimeoutDetails(org.jboss.as.ejb3.concurrency.AccessTimeoutDetails)

Example 2 with AccessTimeoutDetails

use of org.jboss.as.ejb3.concurrency.AccessTimeoutDetails in project wildfly by wildfly.

the class StatefulSessionSynchronizationInterceptor method processInvocation.

@Override
public Object processInvocation(final InterceptorContext context) throws Exception {
    final StatefulSessionComponent component = getComponent(context, StatefulSessionComponent.class);
    final StatefulSessionComponentInstance instance = getComponentInstance(context);
    final OwnableReentrantLock lock = instance.getLock();
    final Object threadLock = instance.getThreadLock();
    final AtomicInteger invocationSyncState = instance.getInvocationSynchState();
    final TransactionSynchronizationRegistry transactionSynchronizationRegistry = component.getTransactionSynchronizationRegistry();
    final Object lockOwner = getLockOwner(transactionSynchronizationRegistry);
    final AccessTimeoutDetails timeout = component.getAccessTimeout(context.getMethod());
    boolean toDiscard = false;
    if (ROOT_LOGGER.isTraceEnabled()) {
        ROOT_LOGGER.trace("Trying to acquire lock: " + lock + " for stateful component instance: " + instance + " during invocation: " + context);
    }
    // we obtain a lock in this synchronization interceptor because the lock needs to be tied to the synchronization
    // so that it can released on the tx synchronization callbacks
    boolean acquired = lock.tryLock(timeout.getValue(), timeout.getTimeUnit(), lockOwner);
    if (!acquired) {
        throw EjbLogger.ROOT_LOGGER.failToObtainLock(component.getComponentName(), timeout.getValue(), timeout.getTimeUnit());
    }
    synchronized (threadLock) {
        //invocation in progress
        invocationSyncState.set(SYNC_STATE_INVOCATION_IN_PROGRESS);
        if (ROOT_LOGGER.isTraceEnabled()) {
            ROOT_LOGGER.trace("Acquired lock: " + lock + " for stateful component instance: " + instance + " during invocation: " + context);
        }
        Object currentTransactionKey = null;
        boolean wasTxSyncRegistered = false;
        try {
            //so enrolling in an existing transaction is not correct
            if (containerManagedTransactions) {
                if (!instance.isSynchronizationRegistered()) {
                    // get the key to current transaction associated with this thread
                    currentTransactionKey = transactionSynchronizationRegistry.getTransactionKey();
                    final int status = transactionSynchronizationRegistry.getTransactionStatus();
                    // if the thread is currently associated with a tx, then register a tx synchronization
                    if (currentTransactionKey != null && status != Status.STATUS_COMMITTED && status != Status.STATUS_ROLLEDBACK) {
                        // register a tx synchronization for this SFSB instance
                        final Synchronization statefulSessionSync = new StatefulSessionSynchronization(instance);
                        transactionSynchronizationRegistry.registerInterposedSynchronization(statefulSessionSync);
                        wasTxSyncRegistered = true;
                        if (ROOT_LOGGER.isTraceEnabled()) {
                            ROOT_LOGGER.trace("Registered tx synchronization: " + statefulSessionSync + " for tx: " + currentTransactionKey + " associated with stateful component instance: " + instance);
                        }
                        // invoke the afterBegin callback on the SFSB
                        instance.afterBegin();
                        instance.setSynchronizationRegistered(true);
                        context.putPrivateData(StatefulTransactionMarker.class, StatefulTransactionMarker.of(true));
                    }
                } else {
                    context.putPrivateData(StatefulTransactionMarker.class, StatefulTransactionMarker.of(false));
                }
            }
            // proceed with the invocation
            try {
                return context.proceed();
            } catch (Exception e) {
                if (component.shouldDiscard(e, context.getMethod())) {
                    toDiscard = true;
                }
                throw e;
            }
        } finally {
            // taken care off by a tx synchronization callbacks.
            if (!wasTxSyncRegistered && !instance.isSynchronizationRegistered()) {
                releaseInstance(instance);
            } else if (!wasTxSyncRegistered) {
                //if we don't release the lock here then it will be acquired multiple times
                //and only released once
                releaseLock(instance);
                //we also call the cache release to decrease the usage count
                if (!instance.isDiscarded()) {
                    instance.getComponent().getCache().release(instance);
                }
            }
            for (; ; ) {
                int state = invocationSyncState.get();
                if (state == SYNC_STATE_INVOCATION_IN_PROGRESS && invocationSyncState.compareAndSet(SYNC_STATE_INVOCATION_IN_PROGRESS, SYNC_STATE_NO_INVOCATION)) {
                    break;
                } else if (state == SYNC_STATE_AFTER_COMPLETE_DELAYED_COMMITTED || state == SYNC_STATE_AFTER_COMPLETE_DELAYED_NO_COMMIT) {
                    try {
                        //invoke the after completion method, other after completion syncs may have already run
                        handleAfterCompletion(state == SYNC_STATE_AFTER_COMPLETE_DELAYED_COMMITTED, instance, toDiscard);
                    } finally {
                        invocationSyncState.set(SYNC_STATE_NO_INVOCATION);
                    }
                } else {
                    EjbLogger.ROOT_LOGGER.unexpectedInvocationState(state);
                    break;
                }
            }
        }
    }
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) TransactionSynchronizationRegistry(javax.transaction.TransactionSynchronizationRegistry) OwnableReentrantLock(org.jboss.as.ejb3.tx.OwnableReentrantLock) AccessTimeoutDetails(org.jboss.as.ejb3.concurrency.AccessTimeoutDetails) Synchronization(javax.transaction.Synchronization) EJBException(javax.ejb.EJBException)

Example 3 with AccessTimeoutDetails

use of org.jboss.as.ejb3.concurrency.AccessTimeoutDetails in project wildfly by wildfly.

the class EjbConcurrencyMergingProcessor method handleDeploymentDescriptor.

protected void handleDeploymentDescriptor(final DeploymentUnit deploymentUnit, final DeploymentReflectionIndex deploymentReflectionIndex, final Class<?> componentClass, final SessionBeanComponentDescription componentConfiguration) throws DeploymentUnitProcessingException {
    if (componentConfiguration.getDescriptorData() == null) {
        return;
    }
    SessionBeanMetaData sessionBeanMetaData = componentConfiguration.getDescriptorData();
    if (sessionBeanMetaData instanceof SessionBean31MetaData) {
        SessionBean31MetaData descriptor = (SessionBean31MetaData) sessionBeanMetaData;
        //handle lock
        if (descriptor.getLockType() != null) {
            componentConfiguration.setBeanLevelLockType(componentConfiguration.getEJBClassName(), descriptor.getLockType());
        }
        //handle access timeout
        if (descriptor.getAccessTimeout() != null) {
            componentConfiguration.setBeanLevelAccessTimeout(componentConfiguration.getEJBClassName(), new AccessTimeoutDetails(descriptor.getAccessTimeout().getTimeout(), descriptor.getAccessTimeout().getUnit()));
        }
        final ConcurrentMethodsMetaData methods = descriptor.getConcurrentMethods();
        if (methods != null) {
            for (final ConcurrentMethodMetaData method : methods) {
                final Method realMethod = resolveMethod(deploymentReflectionIndex, componentClass, componentClass, method.getMethod());
                final MethodIdentifier methodIdentifier = MethodIdentifier.getIdentifierForMethod(realMethod);
                if (method.getLockType() != null) {
                    componentConfiguration.setLockType(method.getLockType(), methodIdentifier);
                }
                if (method.getAccessTimeout() != null) {
                    componentConfiguration.setAccessTimeout(new AccessTimeoutDetails(method.getAccessTimeout().getTimeout(), method.getAccessTimeout().getUnit()), methodIdentifier);
                }
            }
        }
    }
}
Also used : ConcurrentMethodsMetaData(org.jboss.metadata.ejb.spec.ConcurrentMethodsMetaData) SessionBeanMetaData(org.jboss.metadata.ejb.spec.SessionBeanMetaData) AccessTimeoutDetails(org.jboss.as.ejb3.concurrency.AccessTimeoutDetails) ConcurrentMethodMetaData(org.jboss.metadata.ejb.spec.ConcurrentMethodMetaData) Method(java.lang.reflect.Method) MethodIdentifier(org.jboss.invocation.proxy.MethodIdentifier) SessionBean31MetaData(org.jboss.metadata.ejb.spec.SessionBean31MetaData)

Example 4 with AccessTimeoutDetails

use of org.jboss.as.ejb3.concurrency.AccessTimeoutDetails in project wildfly by wildfly.

the class AccessTimeoutAnnotationInformationFactory method fromAnnotation.

@Override
protected AccessTimeoutDetails fromAnnotation(final AnnotationInstance annotationInstance, final PropertyReplacer propertyReplacer) {
    final long timeout = annotationInstance.value().asLong();
    AnnotationValue unitAnnVal = annotationInstance.value("unit");
    final TimeUnit unit = unitAnnVal != null ? TimeUnit.valueOf(unitAnnVal.asEnum()) : TimeUnit.MILLISECONDS;
    return new AccessTimeoutDetails(timeout, unit);
}
Also used : AnnotationValue(org.jboss.jandex.AnnotationValue) TimeUnit(java.util.concurrent.TimeUnit) AccessTimeoutDetails(org.jboss.as.ejb3.concurrency.AccessTimeoutDetails)

Example 5 with AccessTimeoutDetails

use of org.jboss.as.ejb3.concurrency.AccessTimeoutDetails in project wildfly by wildfly.

the class SingletonComponent method getAccessTimeout.

@Override
public AccessTimeoutDetails getAccessTimeout(Method method) {
    final EJBBusinessMethod ejbMethod = new EJBBusinessMethod(method);
    final AccessTimeoutDetails accessTimeout = this.methodAccessTimeouts.get(ejbMethod);
    if (accessTimeout != null) {
        return accessTimeout;
    }
    // check bean level access timeout
    final AccessTimeoutDetails beanTimeout = this.beanLevelAccessTimeout.get(method.getDeclaringClass().getName());
    if (beanTimeout != null) {
        return beanTimeout;
    }
    return getDefaultAccessTimeout();
}
Also used : EJBBusinessMethod(org.jboss.as.ejb3.component.EJBBusinessMethod) AccessTimeoutDetails(org.jboss.as.ejb3.concurrency.AccessTimeoutDetails)

Aggregations

AccessTimeoutDetails (org.jboss.as.ejb3.concurrency.AccessTimeoutDetails)5 EJBBusinessMethod (org.jboss.as.ejb3.component.EJBBusinessMethod)2 Method (java.lang.reflect.Method)1 TimeUnit (java.util.concurrent.TimeUnit)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 EJBException (javax.ejb.EJBException)1 Synchronization (javax.transaction.Synchronization)1 TransactionSynchronizationRegistry (javax.transaction.TransactionSynchronizationRegistry)1 OwnableReentrantLock (org.jboss.as.ejb3.tx.OwnableReentrantLock)1 MethodIdentifier (org.jboss.invocation.proxy.MethodIdentifier)1 AnnotationValue (org.jboss.jandex.AnnotationValue)1 ConcurrentMethodMetaData (org.jboss.metadata.ejb.spec.ConcurrentMethodMetaData)1 ConcurrentMethodsMetaData (org.jboss.metadata.ejb.spec.ConcurrentMethodsMetaData)1 SessionBean31MetaData (org.jboss.metadata.ejb.spec.SessionBean31MetaData)1 SessionBeanMetaData (org.jboss.metadata.ejb.spec.SessionBeanMetaData)1