From d03af155161ccc783b95ce3c0ab39d7f53b7796a Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Sat, 12 Aug 2023 14:50:36 +0200 Subject: [PATCH 1/3] Explicit note on connection pool deadlock with REQUIRES_NEW Closes gh-26250 --- .../transaction/declarative/tx-propagation.adoc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc index 2c29cf7a505..cf4bceac371 100644 --- a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc +++ b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/tx-propagation.adoc @@ -59,6 +59,14 @@ status and with an inner transaction's locks released immediately after its comp Such an independent inner transaction can also declare its own isolation level, timeout, and read-only settings and not inherit an outer transaction's characteristics. +NOTE: The resources attached to the outer transaction will remain bound there while +the inner transaction acquires its own resources such as a new database connection. +This may lead to exhaustion of the connection pool and potentially to a deadlock if +several threads have an active outer transaction and wait to acquire a new connection +for their inner transaction, with the pool not being able to hand out any such inner +connection anymore. Do not use `PROPAGATION_REQUIRES_NEW` unless your connection pool +is appropriately sized, exceeding the number of concurrent threads by at least 1. + [[tx-propagation-nested]] == Understanding `PROPAGATION_NESTED` From 92410395e3e2eeb8b0b4495465f883a8796d34fa Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Sat, 12 Aug 2023 14:50:45 +0200 Subject: [PATCH 2/3] Remove outdated documentation references to WebLogic/WebSphere See gh-22093 --- .../ROOT/pages/core/aop/using-aspectj.adoc | 15 +++----- .../application-server-integration.adoc | 34 +------------------ .../transaction/declarative/annotations.adoc | 7 ++-- .../jms/jca-message-endpoint-manager.adoc | 13 ++++--- .../GenericMessageEndpointManager.java | 8 ++--- .../transaction/TransactionDefinition.java | 4 +-- .../jta/SpringJtaSynchronizationAdapter.java | 31 ++++++++--------- .../transaction/config/spring-tx.xsd | 2 -- 8 files changed, 35 insertions(+), 79 deletions(-) diff --git a/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc b/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc index f9b6b39887d..bdf6d01b707 100644 --- a/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc +++ b/framework-docs/modules/ROOT/pages/core/aop/using-aspectj.adoc @@ -828,13 +828,6 @@ The following table summarizes various `LoadTimeWeaver` implementations: | Running in Red Hat's https://www.jboss.org/jbossas/[JBoss AS] or https://www.wildfly.org/[WildFly] | `JBossLoadTimeWeaver` -| Running in IBM's https://www-01.ibm.com/software/webservers/appserv/was/[WebSphere] -| `WebSphereLoadTimeWeaver` - -| Running in Oracle's - https://www.oracle.com/technetwork/middleware/weblogic/overview/index-085209.html[WebLogic] -| `WebLogicLoadTimeWeaver` - | JVM started with Spring `InstrumentationSavingAgent` (`java -javaagent:path/to/spring-instrument.jar`) | `InstrumentationLoadTimeWeaver` @@ -949,11 +942,11 @@ when you use Spring's LTW support in environments such as application servers an containers. [[aop-aj-ltw-environments-tomcat-jboss-etc]] -==== Tomcat, JBoss, WebSphere, WebLogic +==== Tomcat, JBoss, WildFly -Tomcat, JBoss/WildFly, IBM WebSphere Application Server and Oracle WebLogic Server all -provide a general app `ClassLoader` that is capable of local instrumentation. Spring's -native LTW may leverage those ClassLoader implementations to provide AspectJ weaving. +Tomcat and JBoss/WildFly provide a general app `ClassLoader` that is capable of local +instrumentation. Spring's native LTW may leverage those ClassLoader implementations +to provide AspectJ weaving. You can simply enable load-time weaving, as xref:core/aop/using-aspectj.adoc[described earlier]. Specifically, you do not need to modify the JVM launch script to add `-javaagent:path/to/spring-instrument.jar`. diff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc index abd9418b23a..eb94d951695 100644 --- a/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc +++ b/framework-docs/modules/ROOT/pages/data-access/transaction/application-server-integration.adoc @@ -13,39 +13,7 @@ javadoc for details. Spring's `JtaTransactionManager` is the standard choice to run on Jakarta EE application servers and is known to work on all common servers. Advanced functionality, such as transaction suspension, works on many servers as well (including GlassFish, JBoss and -Geronimo) without any special configuration required. However, for fully supported -transaction suspension and further advanced integration, Spring includes special adapters -for WebLogic Server and WebSphere. These adapters are discussed in the following -sections. - -For standard scenarios, including WebLogic Server and WebSphere, consider using the -convenient `` configuration element. When configured, -this element automatically detects the underlying server and chooses the best -transaction manager available for the platform. This means that you need not explicitly -configure server-specific adapter classes (as discussed in the following sections). -Rather, they are chosen automatically, with the standard -`JtaTransactionManager` as the default fallback. - - -[[transaction-application-server-integration-websphere]] -== IBM WebSphere - -On WebSphere 6.1.0.9 and above, the recommended Spring JTA transaction manager to use is -`WebSphereUowTransactionManager`. This special adapter uses IBM's `UOWManager` API, -which is available in WebSphere Application Server 6.1.0.9 and later. With this adapter, -Spring-driven transaction suspension (suspend and resume as initiated by -`PROPAGATION_REQUIRES_NEW`) is officially supported by IBM. - - -[[transaction-application-server-integration-weblogic]] -== Oracle WebLogic Server - -On WebLogic Server 9.0 or above, you would typically use the -`WebLogicJtaTransactionManager` instead of the stock `JtaTransactionManager` class. This -special WebLogic-specific subclass of the normal `JtaTransactionManager` supports the -full power of Spring's transaction definitions in a WebLogic-managed transaction -environment, beyond standard JTA semantics. Features include transaction names, -per-transaction isolation levels, and proper resuming of transactions in all cases. +Geronimo) without any special configuration required. diff --git a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc index 8a762b791c5..99e09e513db 100644 --- a/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc +++ b/framework-docs/modules/ROOT/pages/data-access/transaction/declarative/annotations.adoc @@ -453,10 +453,9 @@ on rollback rule semantics, patterns, and warnings regarding possible unintentio matches for pattern-based rollback rules. Currently, you cannot have explicit control over the name of a transaction, where 'name' -means the transaction name that appears in a transaction monitor, if applicable -(for example, WebLogic's transaction monitor), and in logging output. For declarative -transactions, the transaction name is always the fully-qualified class name + `.` -+ the method name of the transactionally advised class. For example, if the +means the transaction name that appears in a transaction monitor and in logging output. +For declarative transactions, the transaction name is always the fully-qualified class +name + `.` + the method name of the transactionally advised class. For example, if the `handlePayment(..)` method of the `BusinessService` class started a transaction, the name of the transaction would be: `com.example.BusinessService.handlePayment`. diff --git a/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc b/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc index a36d935806c..23ce156526d 100644 --- a/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc +++ b/framework-docs/modules/ROOT/pages/integration/jms/jca-message-endpoint-manager.adoc @@ -56,14 +56,13 @@ locally, as the following example shows: ---- The specified `WorkManager` can also point to an environment-specific thread pool -- -typically through a `SimpleTaskWorkManager` instance's `asyncTaskExecutor` property. Consider -defining a shared thread pool for all your `ResourceAdapter` instances if you happen to -use multiple adapters. +typically through a `SimpleTaskWorkManager` instance's `asyncTaskExecutor` property. +Consider defining a shared thread pool for all your `ResourceAdapter` instances +if you happen to use multiple adapters. -In some environments (such as WebLogic 9 or above), you can instead obtain the entire `ResourceAdapter` object -from JNDI (by using ``). The Spring-based message -listeners can then interact with the server-hosted `ResourceAdapter`, which also use the -server's built-in `WorkManager`. +In some environments, you can instead obtain the entire `ResourceAdapter` object from JNDI +(by using ``). The Spring-based message listeners can then interact with +the server-hosted `ResourceAdapter`, which also use the server's built-in `WorkManager`. See the javadoc for {api-spring-framework}/jms/listener/endpoint/JmsMessageEndpointManager.html[`JmsMessageEndpointManager`], {api-spring-framework}/jms/listener/endpoint/JmsActivationSpecConfig.html[`JmsActivationSpecConfig`], diff --git a/spring-tx/src/main/java/org/springframework/jca/endpoint/GenericMessageEndpointManager.java b/spring-tx/src/main/java/org/springframework/jca/endpoint/GenericMessageEndpointManager.java index 90b15975d8e..10e5295db6d 100644 --- a/spring-tx/src/main/java/org/springframework/jca/endpoint/GenericMessageEndpointManager.java +++ b/spring-tx/src/main/java/org/springframework/jca/endpoint/GenericMessageEndpointManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -67,9 +67,9 @@ import org.springframework.util.Assert; * * *

The target ResourceAdapter may be configured as a local Spring bean as well - * (the typical case) or obtained from JNDI (e.g. on WebLogic). For the - * example above, a local ResourceAdapter bean could be defined as follows - * (matching the "resourceAdapter" bean reference above): + * (the typical case) or obtained from JNDI. For the example above, a local + * ResourceAdapter bean could be defined as follows (matching the "resourceAdapter" + * bean reference above): * *

  * <bean id="resourceAdapter" class="org.springframework.jca.support.ResourceAdapterFactoryBean">
diff --git a/spring-tx/src/main/java/org/springframework/transaction/TransactionDefinition.java b/spring-tx/src/main/java/org/springframework/transaction/TransactionDefinition.java
index bd373201a60..c7b7c1e7b9f 100644
--- a/spring-tx/src/main/java/org/springframework/transaction/TransactionDefinition.java
+++ b/spring-tx/src/main/java/org/springframework/transaction/TransactionDefinition.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2022 the original author or authors.
+ * Copyright 2002-2023 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -265,7 +265,7 @@ public interface TransactionDefinition {
 	/**
 	 * Return the name of this transaction. Can be {@code null}.
 	 * 

This will be used as the transaction name to be shown in a - * transaction monitor, if applicable (for example, WebLogic's). + * transaction monitor, if applicable. *

In case of Spring's declarative transactions, the exposed name will be * the {@code fully-qualified class name + "." + method name} (by default). * @return the name of this transaction ({@code null} by default} diff --git a/spring-tx/src/main/java/org/springframework/transaction/jta/SpringJtaSynchronizationAdapter.java b/spring-tx/src/main/java/org/springframework/transaction/jta/SpringJtaSynchronizationAdapter.java index 89c5b9a5eee..4beebb30b33 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/jta/SpringJtaSynchronizationAdapter.java +++ b/spring-tx/src/main/java/org/springframework/transaction/jta/SpringJtaSynchronizationAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -67,16 +67,15 @@ public class SpringJtaSynchronizationAdapter implements Synchronization { /** * Create a new SpringJtaSynchronizationAdapter for the given Spring * TransactionSynchronization and JTA TransactionManager. - *

Note that this adapter will never perform a rollback-only call on WebLogic, - * since WebLogic Server is known to automatically mark the transaction as - * rollback-only in case of a {@code beforeCompletion} exception. Hence, - * on WLS, this constructor is equivalent to the single-arg constructor. * @param springSynchronization the Spring TransactionSynchronization to delegate to * @param jtaUserTransaction the JTA UserTransaction to use for rollback-only * setting in case of an exception thrown in {@code beforeCompletion} - * (can be omitted if the JTA provider itself marks the transaction rollback-only - * in such a scenario, which is required by the JTA specification as of JTA 1.1). + * @deprecated as of 6.0.12 since JTA 1.1+ requires implicit rollback-only setting + * in case of an exception thrown in {@code beforeCompletion}, so the regular + * {@link #SpringJtaSynchronizationAdapter(TransactionSynchronization)} constructor + * is sufficient for all scenarios */ + @Deprecated(since = "6.0.12") public SpringJtaSynchronizationAdapter(TransactionSynchronization springSynchronization, @Nullable UserTransaction jtaUserTransaction) { @@ -87,21 +86,21 @@ public class SpringJtaSynchronizationAdapter implements Synchronization { /** * Create a new SpringJtaSynchronizationAdapter for the given Spring * TransactionSynchronization and JTA TransactionManager. - *

Note that this adapter will never perform a rollback-only call on WebLogic, - * since WebLogic Server is known to automatically mark the transaction as - * rollback-only in case of a {@code beforeCompletion} exception. Hence, - * on WLS, this constructor is equivalent to the single-arg constructor. * @param springSynchronization the Spring TransactionSynchronization to delegate to * @param jtaTransactionManager the JTA TransactionManager to use for rollback-only * setting in case of an exception thrown in {@code beforeCompletion} - * (can be omitted if the JTA provider itself marks the transaction rollback-only - * in such a scenario, which is required by the JTA specification as of JTA 1.1) + * @deprecated as of 6.0.12 since JTA 1.1+ requires implicit rollback-only setting + * in case of an exception thrown in {@code beforeCompletion}, so the regular + * {@link #SpringJtaSynchronizationAdapter(TransactionSynchronization)} constructor + * is sufficient for all scenarios */ - public SpringJtaSynchronizationAdapter( - TransactionSynchronization springSynchronization, @Nullable TransactionManager jtaTransactionManager) { + @Deprecated(since = "6.0.12") + public SpringJtaSynchronizationAdapter(TransactionSynchronization springSynchronization, + @Nullable TransactionManager jtaTransactionManager) { this(springSynchronization); - this.jtaTransaction = new UserTransactionAdapter(jtaTransactionManager); + this.jtaTransaction = + (jtaTransactionManager != null ? new UserTransactionAdapter(jtaTransactionManager) : null); } diff --git a/spring-tx/src/main/resources/org/springframework/transaction/config/spring-tx.xsd b/spring-tx/src/main/resources/org/springframework/transaction/config/spring-tx.xsd index f6b3f2fbdc0..62282720004 100644 --- a/spring-tx/src/main/resources/org/springframework/transaction/config/spring-tx.xsd +++ b/spring-tx/src/main/resources/org/springframework/transaction/config/spring-tx.xsd @@ -156,8 +156,6 @@ Date: Sat, 12 Aug 2023 14:51:02 +0200 Subject: [PATCH 3/3] Polishing --- .../beans/factory/support/DefaultListableBeanFactory.java | 3 +-- .../reactive/TransactionSynchronizationManager.java | 6 +++--- .../support/TransactionSynchronizationManager.java | 6 +++--- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java index c7e52d1031f..d8c54764cd2 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java @@ -1664,7 +1664,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto if (priorityCandidate != null) { return priorityCandidate; } - // Fallback + // Fallback: pick directly registered dependency or qualified bean name match for (Map.Entry entry : candidates.entrySet()) { String candidateName = entry.getKey(); Object beanInstance = entry.getValue(); @@ -2083,7 +2083,6 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto public boolean isRequired() { return false; } - @Override @Nullable public Object resolveNotUnique(ResolvableType type, Map matchingBeans) { diff --git a/spring-tx/src/main/java/org/springframework/transaction/reactive/TransactionSynchronizationManager.java b/spring-tx/src/main/java/org/springframework/transaction/reactive/TransactionSynchronizationManager.java index 27ed7f41739..b5a1b11ebad 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/reactive/TransactionSynchronizationManager.java +++ b/spring-tx/src/main/java/org/springframework/transaction/reactive/TransactionSynchronizationManager.java @@ -358,10 +358,10 @@ public class TransactionSynchronizationManager { * Return whether there currently is an actual transaction active. * This indicates whether the current context is associated with an actual * transaction rather than just with active transaction synchronization. - *

To be called by resource management code that wants to discriminate - * between active transaction synchronization (with or without backing + *

To be called by resource management code that wants to differentiate + * between active transaction synchronization (with or without a backing * resource transaction; also on PROPAGATION_SUPPORTS) and an actual - * transaction being active (with backing resource transaction; + * transaction being active (with a backing resource transaction; * on PROPAGATION_REQUIRED, PROPAGATION_REQUIRES_NEW, etc). * @see #isSynchronizationActive() */ diff --git a/spring-tx/src/main/java/org/springframework/transaction/support/TransactionSynchronizationManager.java b/spring-tx/src/main/java/org/springframework/transaction/support/TransactionSynchronizationManager.java index ec887879959..85cd680ad8b 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/support/TransactionSynchronizationManager.java +++ b/spring-tx/src/main/java/org/springframework/transaction/support/TransactionSynchronizationManager.java @@ -426,10 +426,10 @@ public abstract class TransactionSynchronizationManager { * Return whether there currently is an actual transaction active. * This indicates whether the current thread is associated with an actual * transaction rather than just with active transaction synchronization. - *

To be called by resource management code that wants to discriminate - * between active transaction synchronization (with or without backing + *

To be called by resource management code that wants to differentiate + * between active transaction synchronization (with or without a backing * resource transaction; also on PROPAGATION_SUPPORTS) and an actual - * transaction being active (with backing resource transaction; + * transaction being active (with a backing resource transaction; * on PROPAGATION_REQUIRED, PROPAGATION_REQUIRES_NEW, etc). * @see #isSynchronizationActive() */