diff --git a/de.metas.adempiere.adempiere/base/src/main/java/org/adempiere/ad/trx/api/ITrxManager.java b/de.metas.adempiere.adempiere/base/src/main/java/org/adempiere/ad/trx/api/ITrxManager.java index 21c7d7c038b..3b4d39374e2 100644 --- a/de.metas.adempiere.adempiere/base/src/main/java/org/adempiere/ad/trx/api/ITrxManager.java +++ b/de.metas.adempiere.adempiere/base/src/main/java/org/adempiere/ad/trx/api/ITrxManager.java @@ -339,8 +339,6 @@ default T callInThreadInheritedTrx(@NonNull final TrxCallable callable) * * this method will return a pseudo- {@link ITrxListenerManager} which automatically commits when a listener is registered. * - * - * @param trxName * @return auto-commit {@link ITrxListenerManager}; never returns null */ ITrxListenerManager getTrxListenerManagerOrAutoCommit(String trxName); diff --git a/de.metas.adempiere.adempiere/base/src/main/java/org/adempiere/ad/trx/api/impl/AbstractTrx.java b/de.metas.adempiere.adempiere/base/src/main/java/org/adempiere/ad/trx/api/impl/AbstractTrx.java index b5125528a52..cd6d8996c4e 100644 --- a/de.metas.adempiere.adempiere/base/src/main/java/org/adempiere/ad/trx/api/impl/AbstractTrx.java +++ b/de.metas.adempiere.adempiere/base/src/main/java/org/adempiere/ad/trx/api/impl/AbstractTrx.java @@ -471,7 +471,7 @@ private ITrxListenerManager getTrxListenerManager(final boolean create) if (create) { - trxListenerManager = new TrxListenerManager(); + trxListenerManager = new TrxListenerManager(getTrxName()); return trxListenerManager; } @@ -489,7 +489,7 @@ public final ITrxManager getTrxManager() { return trxManager; } - + private final Map getPropertiesMap() { if(_properties == null) @@ -504,7 +504,7 @@ private final Map getPropertiesMap() } return _properties; } - + private final Map getPropertiesMapOrNull() { synchronized (this) @@ -517,7 +517,7 @@ private final Map getPropertiesMapOrNull() public final T setProperty(final String name, final Object value) { Check.assumeNotEmpty(name, "name is not empty"); - + // Handle null value case if(value == null) { @@ -526,7 +526,7 @@ public final T setProperty(final String name, final Object value) { return null; } - + @SuppressWarnings("unchecked") final T valueOld = (T)properties.remove(name); return valueOld; @@ -554,7 +554,7 @@ public T getProperty(final String name, final Supplier valueInitializer) final T value = (T)getPropertiesMap().computeIfAbsent(name, key->valueInitializer.get()); return value; } - + @Override public T getProperty(final String name, final Function valueInitializer) { @@ -562,21 +562,21 @@ public T getProperty(final String name, final Function valueInitial final T value = (T)getPropertiesMap().computeIfAbsent(name, key->valueInitializer.apply(this)); return value; } - + @Override public T setAndGetProperty(@NonNull final String name, @NonNull final Function valueRemappingFunction) { final BiFunction remappingFunction = (propertyName, oldValue) -> { @SuppressWarnings("unchecked") final T oldValueCasted = (T)oldValue; - + return valueRemappingFunction.apply(oldValueCasted); }; - + @SuppressWarnings("unchecked") final T value = (T)getPropertiesMap().compute(name, remappingFunction); return value; - + } diff --git a/de.metas.adempiere.adempiere/base/src/main/java/org/adempiere/ad/trx/api/impl/AbstractTrxManager.java b/de.metas.adempiere.adempiere/base/src/main/java/org/adempiere/ad/trx/api/impl/AbstractTrxManager.java index 4a8452f5485..5f2b05f3c22 100644 --- a/de.metas.adempiere.adempiere/base/src/main/java/org/adempiere/ad/trx/api/impl/AbstractTrxManager.java +++ b/de.metas.adempiere.adempiere/base/src/main/java/org/adempiere/ad/trx/api/impl/AbstractTrxManager.java @@ -92,11 +92,9 @@ public abstract class AbstractTrxManager implements ITrxManager private ITrxNameGenerator trxNameGenerator = DefaultTrxNameGenerator.instance; - /** - * Thread level transaction name - */ - private final InheritableThreadLocal threadLocalTrx = new InheritableThreadLocal<>(); - private final InheritableThreadLocal threadLocalOnRunnableFail = new InheritableThreadLocal<>(); + /** Name of the trx currently associated with this thread */ + private final ThreadLocal threadLocalTrx = new ThreadLocal<>(); + private final ThreadLocal threadLocalOnRunnableFail = new ThreadLocal<>(); private boolean debugTrxCreateStacktrace = false; private boolean debugTrxCloseStacktrace = false; @@ -110,8 +108,6 @@ public abstract class AbstractTrxManager implements ITrxManager public AbstractTrxManager() { - super(); - final JMXTrxManager jmxBean = new JMXTrxManager(this); JMXRegistry.get().registerJMX(jmxBean, OnJMXAlreadyExistsPolicy.Replace); } @@ -664,7 +660,7 @@ else if (trxPropagation == TrxPropagation.NESTED) // Set our transaction as currently active thread local transaction restoreThreadLocalTrxName = true; - threadLocalTrx.set(trxNameToUse); + setThreadInheritedTrxName(trxNameToUse); return call0(callable, cfg, trxNameToUse); } @@ -673,7 +669,7 @@ else if (trxPropagation == TrxPropagation.NESTED) // Restore the thread local transaction, in case we changed it. if (restoreThreadLocalTrxName) { - threadLocalTrx.set(threadLocalTrxNameOld); + setThreadInheritedTrxName(threadLocalTrxNameOld); restoreThreadLocalTrxName = false; } diff --git a/de.metas.adempiere.adempiere/base/src/main/java/org/adempiere/ad/trx/api/impl/TrxListenerManager.java b/de.metas.adempiere.adempiere/base/src/main/java/org/adempiere/ad/trx/api/impl/TrxListenerManager.java index 7d91ec2f442..f27d766a10e 100644 --- a/de.metas.adempiere.adempiere/base/src/main/java/org/adempiere/ad/trx/api/impl/TrxListenerManager.java +++ b/de.metas.adempiere.adempiere/base/src/main/java/org/adempiere/ad/trx/api/impl/TrxListenerManager.java @@ -42,9 +42,6 @@ /** * Default {@link ITrxListenerManager} implementation - * - * @author tsa - * */ public class TrxListenerManager implements ITrxListenerManager { @@ -52,18 +49,22 @@ public class TrxListenerManager implements ITrxListenerManager private volatile WeakList listeners = null; + /** for debugging */ + private final String trxName; + /** * Never contains {@code null} or {@link TrxEventTiming#UNSPECIFIED}. */ private final AtomicReference runningWithinTrxEventTiming = new AtomicReference<>(TrxEventTiming.NONE); - private static enum OnError + private enum OnError { ThrowException, LogAndSkip - }; + } - public TrxListenerManager() + public TrxListenerManager(final String trxName) { + this.trxName = trxName; } @Override @@ -95,20 +96,22 @@ public void registerListener(@NonNull final RegisterListenerRequest listener) private void verifyEventTiming(@NonNull final RegisterListenerRequest listener) { final TrxEventTiming eventTimingOfListener = listener.getTiming(); - final boolean listenerHasProblematicTiming = !eventTimingOfListener.canBeRegisteredWithinOtherTiming(runningWithinTrxEventTiming.get()); + final TrxEventTiming currentTiming = runningWithinTrxEventTiming.get(); + final boolean listenerHasProblematicTiming = !eventTimingOfListener.canBeRegisteredWithinOtherTiming(currentTiming); if (listenerHasProblematicTiming) { final String message = StringUtils.formatMessage("Registering another listener within a listener's event handling code might be a development error and that other listener might not be fired." + + "\n trxName={}" + "\n current trx event timing={}" + "\n listener that is registerd={}", - runningWithinTrxEventTiming.get(), + this.trxName, + currentTiming, listener); - new AdempiereException(message).throwIfDeveloperModeOrLogWarningElse(logger); } } - + @Override public boolean canRegisterOnTiming(@NonNull final TrxEventTiming timing) {