Skip to content

Commit

Permalink
Document use of multiple datasources in a single transaction
Browse files Browse the repository at this point in the history
(cherry picked from commit b16dde5)
  • Loading branch information
yrodiere authored and gsmet committed May 14, 2024
1 parent 3f0fb61 commit 21abdf6
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 2 deletions.
70 changes: 70 additions & 0 deletions docs/src/main/asciidoc/datasource.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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 <<extensions-and-database-drivers-reference,supported JDBC drivers do>>,
but <<other-databases,other JDBC drivers>> might not.
. Make sure your database server is configured to enable XA.
. Enable XA support explicitly for each relevant datasource by setting
<<quarkus-agroal_quarkus-datasource-jdbc-transactions,`quarkus.datasource[.optional name].transactions`>> 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
* <p>
* 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.
*
Expand Down

0 comments on commit 21abdf6

Please sign in to comment.