com.arjuna.ats.jta.cdi.TransactionContext Maven / Gradle / Ivy
/*
* JBoss, Home of Professional Open Source.
* Copyright 2013-2018, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package com.arjuna.ats.jta.cdi;
import com.arjuna.ats.jta.common.jtaPropertyManager;
import com.arjuna.ats.jta.logging.jtaLogger;
import javax.enterprise.context.ContextNotActiveException;
import javax.enterprise.context.spi.Context;
import javax.enterprise.context.spi.Contextual;
import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.spi.PassivationCapable;
import javax.transaction.Status;
import javax.transaction.SystemException;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
import javax.transaction.TransactionScoped;
import javax.transaction.TransactionSynchronizationRegistry;
import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.function.Supplier;
/**
* @author [email protected] 01/05/2013
*
* @author Laird Nelson
*/
public class TransactionContext implements Context {
private final Supplier transactionManagerSupplier;
private final Supplier transactionSynchronizationRegistrySupplier;
private final Map> transactions = new HashMap<>();
/**
* Creates a new {@link TransactionContext}.
*
* @deprecated Please use the {@link #TransactionContext(Supplier,
* Supplier)} constructor instead.
*/
@Deprecated
public TransactionContext() {
this(() -> jtaPropertyManager.getJTAEnvironmentBean().getTransactionManager(),
() -> jtaPropertyManager.getJTAEnvironmentBean().getTransactionSynchronizationRegistry());
}
/**
* Creates a new {@link TransactionContext}.
*
* @param transactionManagerSupplier a {@link Supplier} of a
* {@link TransactionManager}; must not be {@code null}
*
* @param transactionSynchronizationRegistrySupplier a {@link
* Supplier} of a {@link TransactionSynchronizationRegistry}; must
* not be {@code null}
*
* @exception NullPointerException if either parameter is {@code null}
*/
public TransactionContext(Supplier transactionManagerSupplier,
Supplier transactionSynchronizationRegistrySupplier) {
super();
this.transactionManagerSupplier = Objects.requireNonNull(transactionManagerSupplier);
this.transactionSynchronizationRegistrySupplier = Objects.requireNonNull(transactionSynchronizationRegistrySupplier);
}
@Override
public Class extends Annotation> getScope() {
return TransactionScoped.class;
}
@Override
public T get(Contextual contextual, CreationalContext creationalContext) {
if (!isActive()) {
throw new ContextNotActiveException(jtaLogger.i18NLogger.get_contextual_is_not_active());
}
if (contextual == null) {
throw new RuntimeException(jtaLogger.i18NLogger.get_contextual_is_null());
}
PassivationCapable bean = (PassivationCapable) contextual;
TransactionSynchronizationRegistry tsr = this.transactionSynchronizationRegistrySupplier.get();
@SuppressWarnings("unchecked")
final T resource = (T) tsr.getResource(bean.getId());
if (resource != null) {
return resource;
} else if (creationalContext != null) {
Transaction currentTransaction = getCurrentTransaction();
T t = contextual.create(creationalContext);
tsr.putResource(bean.getId(), t);
synchronized (transactions) {
@SuppressWarnings("unchecked")
TransactionScopeCleanup synch = (TransactionScopeCleanup) transactions.get(currentTransaction);
if (synch == null) {
synch = new TransactionScopeCleanup<>(this, currentTransaction);
transactions.put(currentTransaction, synch);
}
synch.registerBean(contextual, creationalContext, t);
}
return t;
} else {
return null;
}
}
@Override
public T get(Contextual contextual) {
return get(contextual, null);
}
@Override
public boolean isActive() {
// Note that scope initialization and destruction events are
// fired by NarayanaTransactionManager. See
// https://issues.jboss.org/browse/JBTM-3106 for details.
Transaction transaction = getCurrentTransaction();
if (transaction == null) {
return false;
}
try {
int currentStatus = transaction.getStatus();
return currentStatus == Status.STATUS_ACTIVE ||
currentStatus == Status.STATUS_MARKED_ROLLBACK ||
currentStatus == Status.STATUS_PREPARED ||
currentStatus == Status.STATUS_UNKNOWN ||
currentStatus == Status.STATUS_PREPARING ||
currentStatus == Status.STATUS_COMMITTING ||
currentStatus == Status.STATUS_ROLLING_BACK;
} catch (SystemException e) {
throw new RuntimeException(jtaLogger.i18NLogger.get_error_getting_tx_status(), e);
}
}
void cleanupScope(Transaction transaction) {
synchronized (transactions) {
transactions.remove(transaction);
}
}
private Transaction getCurrentTransaction() {
try {
return this.transactionManagerSupplier.get().getTransaction();
} catch (SystemException e) {
throw new RuntimeException(jtaLogger.i18NLogger.get_error_getting_current_tx(), e);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy