diff --git a/docs/src/main/asciidoc/datasource.adoc b/docs/src/main/asciidoc/datasource.adoc index a56046cb64efd..749c8e22b0d1d 100644 --- a/docs/src/main/asciidoc/datasource.adoc +++ b/docs/src/main/asciidoc/datasource.adoc @@ -517,6 +517,76 @@ public class MyProducer { ---- ==== +[[datasource-multiple-single-transaction]] +=== Use multiple datasources in a single transaction + +By default, XA support on datasources is disabled, +and thus a transaction may include at most one datasource. +Attempting to access multiple non-XA datasources in the same transaction +would result in an exception similar to this: + +[source] +---- +... +Caused by: java.sql.SQLException: Exception in association of connection to existing transaction + at io.agroal.narayana.NarayanaTransactionIntegration.associate(NarayanaTransactionIntegration.java:130) + ... +Caused by: java.sql.SQLException: Unable to enlist connection to existing transaction + at io.agroal.narayana.NarayanaTransactionIntegration.associate(NarayanaTransactionIntegration.java:121) + ... +---- + +To allow using multiple JDBC datasources in the same transaction: + +. Make sure your JDBC driver supports XA. +All <>, +but <> might not. +. Make sure your database server is configured to enable XA. +. Enable XA support explicitly for each relevant datasource by setting +<> to `xa`. + +Using XA, a rollback in one datasource will trigger a rollback in every other datasource enrolled in the transaction. + +[NOTE] +==== +XA transactions on reactive datasources are not supported at the moment. +==== + +[NOTE] +==== +If your transaction involves other, non-datasource resources, +keep in mind *those* resources might not support XA transactions, +or might require additional configuration. +==== + +If XA cannot be enabled for one of your datasources: + +* Be aware that enabling XA for all datasources _except one_ (and only one) is still supported +through https://www.narayana.io/docs/project/index.html#d5e857[Last Resource Commit Optimization (LRCO)]. +* If you do not need a rollback for one datasource to trigger a rollback for other datasources, +consider splitting your code into multiple transactions. +To that end, use xref:transaction.adoc#programmatic-approach[`QuarkusTransaction.requiringNew()`]/xref:transaction.adoc#declarative-approach[`@Transactional(REQUIRES_NEW)`] (preferably) +or xref:transaction.adoc#legacy-api-approach[`UserTransaction`] (for more complex use cases). + +[CAUTION] +==== +As a last resort, and for compatibility with Quarkus 3.8 and earlier, +you may allow unsafe transaction handling across multiple non-XA datasources +by setting `quarkus.transaction-manager.allow-unsafe-multiple-last-resources` to `true`. + +With this property set to `true`, a transaction rollback +could possibly be applied to only some of the non-XA datasources, +with other non-XA datasources having already committed their changes, +leaving your overall system in an inconsistent state. + +We do not recommend using this configuration property, +and we plan to remove it in the future, +so you should plan fixing your application accordingly. +If you think your use case of this feature is valid and this option should be kept around, +open an issue in the https://github.com/quarkusio/quarkus/issues/new?assignees=&labels=kind%2Fenhancement&projects=&template=feature_request.yml[Quarkus tracker] +explaining why. +==== + == Datasource integrations === Datasource health check diff --git a/extensions/narayana-jta/runtime/src/main/java/io/quarkus/narayana/jta/runtime/TransactionManagerBuildTimeConfig.java b/extensions/narayana-jta/runtime/src/main/java/io/quarkus/narayana/jta/runtime/TransactionManagerBuildTimeConfig.java index 7641eab337ce1..b8822e6893916 100644 --- a/extensions/narayana-jta/runtime/src/main/java/io/quarkus/narayana/jta/runtime/TransactionManagerBuildTimeConfig.java +++ b/extensions/narayana-jta/runtime/src/main/java/io/quarkus/narayana/jta/runtime/TransactionManagerBuildTimeConfig.java @@ -20,8 +20,8 @@ public final class TransactionManagerBuildTimeConfig { * recommended since the probability of inconsistent outcomes is significantly higher and * much harder to recover from than LRCO. For this reason, use LRCO as a last resort. *

- * We plan to remove this property in the future so you should plan fixing your application - * accordingly. + * We do not recommend using this configuration property, and we plan to remove it in the future, + * so you should plan fixing your application accordingly. * If you think your use case of this feature is valid and this option should be kept around, * open an issue in our tracker explaining why. *