Skip to content

Commit

Permalink
The-data-source-review-for-3-15
Browse files Browse the repository at this point in the history
Applying feedback from the SME review

Signed-off-by: Michal Maléř <[email protected]>
  • Loading branch information
MichalMaler committed Sep 19, 2024
1 parent 5f90272 commit 18ea2b3
Showing 1 changed file with 56 additions and 83 deletions.
139 changes: 56 additions & 83 deletions docs/src/main/asciidoc/datasource.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ See, https://docs.oracle.com/javase/tutorial/jdbc/basics/connecting.html
Applications use datasources to access relational databases.
Quarkus provides a unified configuration model to define datasources for Java Database Connectivity (JDBC) and Reactive database drivers.

Quarkus uses link:https://agroal.github.io/[Agroal] and link:https://vertx.io/[Vert.x] to provide high-performance, scalable data source connection pooling for JDBC and reactive drivers.
The `quarkus-jdbc-\*` and `quarkus-reactive-*-client` extensions provide build time optimizations and integrate configured data sources with Quarkus features like security, health checks, and metrics.
Quarkus uses link:https://agroal.github.io/[Agroal] and link:https://vertx.io/[Vert.x] to provide high-performance, scalable datasource connection pooling for JDBC and reactive drivers.
The `quarkus-jdbc-\*` and `quarkus-reactive-*-client` extensions provide build time optimizations and integrate configured datasources with Quarkus features like security, health checks, and metrics.

For more information about consuming and using a reactive datasource, see the Quarkus xref:reactive-sql-clients.adoc[Reactive SQL clients] guide.

Check warning on line 28 in docs/src/main/asciidoc/datasource.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsSuggestions] Depending on the context, consider using 'by using' or 'that uses' rather than 'using'. Raw Output: {"message": "[Quarkus.TermsSuggestions] Depending on the context, consider using 'by using' or 'that uses' rather than 'using'.", "location": {"path": "docs/src/main/asciidoc/datasource.adoc", "range": {"start": {"line": 28, "column": 41}}}, "severity": "INFO"}

Expand All @@ -32,7 +32,7 @@ Additionally, refer to the Quarkus xref:hibernate-orm.adoc[Hibernate ORM] guide

== Get started with configuring `datasources` in Quarkus

For users familiar with the fundamentals, this section provides an overview and code samples to set up data sources quickly.
For users familiar with the fundamentals, this section provides an overview and code samples to set up datasources quickly.

For more advanced configuration with examples, see <<datasource-reference>>.

Check warning on line 37 in docs/src/main/asciidoc/datasource.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsSuggestions] Depending on the context, consider using 'because' or 'while' rather than 'as'. Raw Output: {"message": "[Quarkus.TermsSuggestions] Depending on the context, consider using 'because' or 'while' rather than 'as'.", "location": {"path": "docs/src/main/asciidoc/datasource.adoc", "range": {"start": {"line": 37, "column": 57}}}, "severity": "INFO"}

Expand All @@ -48,7 +48,8 @@ In dev mode, if you do not provide any explicit database connection details, Qua
If you provide user credentials, the underlying database will be configured to use them.
This is useful if you want to connect to the database with an external tool.

To use this feature, ensure a Docker or Podman container runtime is installed, depending on the database type. Certain databases, such as H2, operate in in-memory mode and do not require a container runtime.
To use this feature, ensure a Docker or Podman container runtime is installed, depending on the database type.
Certain databases, such as H2, operate in in-memory mode and do not require a container runtime.

TIP: Prefix the actual connection details for prod mode with `%prod.` to ensure they are not applied in dev mode.
For more information, see the xref:config-reference.adoc#profiles[Profiles] section of the "Configuration reference" guide.
Expand All @@ -73,7 +74,7 @@ For more details and optional configurations, see xref:databases-dev-services.ad

. Configure your JDBC datasource:
+
[source, properties]
[source,properties]
----
quarkus.datasource.db-kind=postgresql <1>
quarkus.datasource.username=<your username>
Expand Down Expand Up @@ -111,7 +112,7 @@ endif::no-quarkus-reactive-db2-client[]

. Configure your reactive datasource:
+
[source, properties]
[source,properties]
----
quarkus.datasource.db-kind=postgresql <1>
quarkus.datasource.username=<your username>
Expand All @@ -136,7 +137,7 @@ This depends on the configuration and the selection of project extensions.

. Define a datasource with the following configuration property, where `db-kind` defines which database platform to connect to, for example, `h2`:

Check warning on line 138 in docs/src/main/asciidoc/datasource.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsSuggestions] Depending on the context, consider using ', which (non restrictive clause preceded by a comma)' or 'that (restrictive clause without a comma)' rather than 'which'. Raw Output: {"message": "[Quarkus.TermsSuggestions] Depending on the context, consider using ', which (non restrictive clause preceded by a comma)' or 'that (restrictive clause without a comma)' rather than 'which'.", "location": {"path": "docs/src/main/asciidoc/datasource.adoc", "range": {"start": {"line": 138, "column": 89}}}, "severity": "INFO"}
+
[source, properties]
[source,properties]
----
quarkus.datasource.db-kind=h2
----
Expand Down Expand Up @@ -168,7 +169,7 @@ For native executable builds, it is recommended to either use the available JDBC

. Configure the following properties to define credentials:
+
[source, properties]
[source,properties]
----
quarkus.datasource.username=<your username>
quarkus.datasource.password=<your password>
Expand Down Expand Up @@ -232,7 +233,7 @@ To use a JDBC driver for another database, <<other-databases,use a database with

. Configure the JDBC connection by defining the JDBC URL property:
+
[source, properties]
[source,properties]
----
quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5432/hibernate_orm_test
----
Expand All @@ -259,19 +260,20 @@ If you plan to make a native executable, use the existing JDBC Quarkus extension

[WARNING]
====
OpenTracing has been deprecated in favor of OpenTelemetry. For tracing information, please check the related section about <<datasource-tracing>>, bellow.
OpenTracing has been deprecated in favor of OpenTelemetry.
For tracing information, please check the related section about <<datasource-tracing>>, bellow.
====

.A custom driver definition example with the legacy OpenTracing driver:

[source, properties]
[source,properties]
----
quarkus.datasource.jdbc.driver=io.opentracing.contrib.jdbc.TracingDriver
----

.An example for defining access to a database with no built-in support in JVM mode:

[source, properties]
[source,properties]
----
quarkus.datasource.db-kind=other
quarkus.datasource.jdbc.driver=oracle.jdbc.driver.OracleDriver
Expand Down Expand Up @@ -335,29 +337,28 @@ For more information about pool size adjustment properties, see the <<reactive-c
[[jdbc-and-reactive-datasources-simultaneously]]
==== JDBC and reactive datasources simultaneously

Check warning on line 338 in docs/src/main/asciidoc/datasource.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.Headings] Use sentence-style capitalization in 'JDBC and reactive datasources simultaneously'. Raw Output: {"message": "[Quarkus.Headings] Use sentence-style capitalization in 'JDBC and reactive datasources simultaneously'.", "location": {"path": "docs/src/main/asciidoc/datasource.adoc", "range": {"start": {"line": 338, "column": 6}}}, "severity": "INFO"}

When a JDBC extension - along with Agroal - and a reactive datasource extension handling the given database kind are included, they will both be created by default.

If you want to use them both,
make sure to set both <<jdbc-datasource,JDBC>> and <<reactive-datasource,reactive>> configuration,
for example:
When both a JDBC extension and a reactive datasource extension for the same database kind are included, both JDBC and reactive datasources will be created by default.

* To use the <<jdbc-datasource,JDBC>> and <<reactive-datasource,reactive>> datasourceces simultaneously:
+
[source,properties]
----
%prod.quarkus.datasource.reactive.url=postgresql:///your_database
%prod.quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5432/hibernate_orm_test
----

If you do not want to have both a JDBC datasource and a reactive datasource created, use the following configuration.

* To disable the JDBC datasource explicitly:
+
[source, properties]
[source,properties]
----
quarkus.datasource.jdbc=false
----

* To disable the reactive datasource explicitly:
+
[source, properties]
[source,properties]
----
quarkus.datasource.reactive=false
----
Expand Down Expand Up @@ -430,26 +431,23 @@ AgroalDataSource inventoryDataSource;
----

[[datasource-active]]
=== Activate/deactivate datasources
=== Activate or deactivate datasources

If a datasource is configured at build time,
by default it is active at runtime,
that is Quarkus will start the corresponding JDBC connection pool or reactive client on application startup.
When a datasource is configured at build time, it is active by default at runtime.
This means that Quarkus will start the corresponding JDBC connection pool or reactive client when the application starts.

To deactivate a datasource at runtime, set `quarkus.datasource[.optional name].active` to `false`.
Then Quarkus will not start the corresponding JDBC connection pool or reactive client on application startup.
Any attempt to use the corresponding datasource at runtime will fail with a clear error message.
Quarkus will then skip starting the JDBC connection pool or reactive client during application startup.
Any attempt to use the deactivated datasource at runtime results in an exception.

This is in particular useful when you want an application to be able
to use one of a pre-determined set of datasources at runtime.
This feature is especially useful when you need the application to select one datasource from a predefined set at runtime.

[WARNING]
====
If another Quarkus extension relies on an inactive datasource,
that extension might fail to start.
If another Quarkus extension relies on an inactive datasource, that extension might fail to start.

Check warning on line 447 in docs/src/main/asciidoc/datasource.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsSuggestions] Depending on the context, consider using ', which (non restrictive clause preceded by a comma)' or 'that (restrictive clause without a comma)' rather than ', that'. Raw Output: {"message": "[Quarkus.TermsSuggestions] Depending on the context, consider using ', which (non restrictive clause preceded by a comma)' or 'that (restrictive clause without a comma)' rather than ', that'.", "location": {"path": "docs/src/main/asciidoc/datasource.adoc", "range": {"start": {"line": 447, "column": 62}}}, "severity": "INFO"}
In such case, you will need to deactivate that other extension too.
For example see xref:hibernate-orm.adoc#persistence-unit-active[here for Hibernate ORM].
In such a case, you will need to deactivate that other extension as well.

Check warning on line 449 in docs/src/main/asciidoc/datasource.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.Fluff] Depending on the context, consider using 'Rewrite the sentence, or use 'must', instead of' rather than 'need to'. Raw Output: {"message": "[Quarkus.Fluff] Depending on the context, consider using 'Rewrite the sentence, or use 'must', instead of' rather than 'need to'.", "location": {"path": "docs/src/main/asciidoc/datasource.adoc", "range": {"start": {"line": 449, "column": 21}}}, "severity": "INFO"}

Check warning on line 449 in docs/src/main/asciidoc/datasource.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsSuggestions] Depending on the context, consider using 'because' or 'while' rather than 'as'. Raw Output: {"message": "[Quarkus.TermsSuggestions] Depending on the context, consider using 'because' or 'while' rather than 'as'.", "location": {"path": "docs/src/main/asciidoc/datasource.adoc", "range": {"start": {"line": 449, "column": 61}}}, "severity": "INFO"}
For an example of this scenario, see the xref:hibernate-orm.adoc#persistence-unit-active[Hibernate ORM] section.
====

For example, with the following configuration:
Expand All @@ -465,10 +463,7 @@ quarkus.datasource."oracle".active=false
quarkus.datasource."oracle".jdbc.url=jdbc:oracle:///your_database
----

Setting `quarkus.datasource."pg".active=true` xref:config-reference.adoc#configuration-sources[at runtime]
will make only the PostgreSQL datasource available,
and setting `quarkus.datasource."oracle".active=true` at runtime
will make only the Oracle datasource available.
Setting `quarkus.datasource."pg".active=true` xref:config-reference.adoc#configuration-sources[at runtime] will make only the PostgreSQL datasource available, and setting `quarkus.datasource."oracle".active=true` at runtime will make only the Oracle datasource available.

[TIP]
====
Expand All @@ -492,8 +487,7 @@ xref:config-reference.adoc#multiple-profiles[setting `quarkus.profile`]:

[TIP]
====
It can also be useful to define a xref:cdi.adoc#ok-you-said-that-there-are-several-kinds-of-beans[CDI bean producer] redirecting to the currently active datasource,
like this:
It can also be useful to define a xref:cdi.adoc#ok-you-said-that-there-are-several-kinds-of-beans[CDI bean producer] redirecting to the currently active datasource, like this:
[source,java,indent=0]
----
Expand Down Expand Up @@ -525,10 +519,8 @@ 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:
By default, XA support on datasources is disabled. Therefore, a transaction might include no more than one datasource.
Attempting to access multiple non-XA datasources in the same transaction results in an exception similar to the following:

[source]
----
Expand All @@ -544,11 +536,9 @@ Caused by: java.sql.SQLException: Failed to enlist. Check if a connection from a
To allow using multiple JDBC datasources in the same transaction:

Check warning on line 536 in docs/src/main/asciidoc/datasource.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsSuggestions] Depending on the context, consider using 'by using' or 'that uses' rather than 'using'. Raw Output: {"message": "[Quarkus.TermsSuggestions] Depending on the context, consider using 'by using' or 'that uses' rather than 'using'.", "location": {"path": "docs/src/main/asciidoc/datasource.adoc", "range": {"start": {"line": 536, "column": 9}}}, "severity": "INFO"}

Check warning on line 536 in docs/src/main/asciidoc/datasource.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsWarnings] Consider using 'verify' rather than 'Make sure' unless updating existing content that uses the term. Raw Output: {"message": "[Quarkus.TermsWarnings] Consider using 'verify' rather than 'Make sure' unless updating existing content that uses the term.", "location": {"path": "docs/src/main/asciidoc/datasource.adoc", "range": {"start": {"line": 536, "column": 60}}}, "severity": "WARNING"}

. 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.
All <<extensions-and-database-drivers-reference,supported JDBC drivers do>>, but <<other-databases,other JDBC drivers>> might not.

Check warning on line 539 in docs/src/main/asciidoc/datasource.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsWarnings] Consider using 'verify' rather than 'Make sure' unless updating existing content that uses the term. Raw Output: {"message": "[Quarkus.TermsWarnings] Consider using 'verify' rather than 'Make sure' unless updating existing content that uses the term.", "location": {"path": "docs/src/main/asciidoc/datasource.adoc", "range": {"start": {"line": 539, "column": 124}}}, "severity": "WARNING"}
. 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].jdbc.transactions`>> to `xa`.
. Enable XA support explicitly for each relevant datasource by setting <<quarkus-agroal_quarkus-datasource-jdbc-transactions,`quarkus.datasource[.optional name].jdbc.transactions`>> to `xa`.

Using XA, a rollback in one datasource will trigger a rollback in every other datasource enrolled in the transaction.

Expand All @@ -559,44 +549,28 @@ 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 your transaction involves other non-datasource resources, keep in mind these 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).
* 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 do so, 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.unsafe-multiple-last-resources` to `allow`.
With this property set to `allow`, 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.
Alternatively, you can allow the same unsafe behavior,
but with warnings when it is taken advantage of:
* setting the property to `warn-each`
would result in logging a warning on *each* offending transaction.
* setting the property to `warn-first`
would result in logging a warning on the *first* offending transaction.
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]
If no other solution works, and to maintain compatibility with Quarkus 3.8 and earlier, set `quarkus.transaction-manager.unsafe-multiple-last-resources` to `allow` to enable unsafe transaction handling across multiple non-XA datasources.
With this property set to `allow`, a transaction rollback could only be applied to the last non-XA datasource, while other non-XA datasources could have already committed their changes, potentially leaving your overall system in an inconsistent state.
Alternatively, you can allow the same unsafe behavior, but with warnings when it takes effect:
* Setting the property to `warn-each` results in logging a warning on *each* offending transaction.
* Setting the property to `warn-first` results in logging a warning on the *first* offending transaction.
We do not recommend using this configuration property, and we plan to remove it in the future, so you should fix 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 link:https://github.com/quarkusio/quarkus/issues/new?assignees=&labels=kind%2Fenhancement&projects=&template=feature_request.yml[Quarkus tracker]
explaining why.
====

Expand All @@ -611,7 +585,7 @@ If you have multiple datasources, all datasources are checked, and if a single d

This behavior can be disabled by using the `quarkus.datasource.health.enabled` property.

To exclude only a particular datasource from the health check, use:
To exclude only a particular datasource from the health check:

[source,properties]
----
Expand All @@ -626,8 +600,7 @@ This can be activated by setting the `quarkus.datasource.metrics.enabled` proper
For the exposed metrics to contain any actual values, a metric collection must be enabled internally by the Agroal mechanisms.
By default, this metric collection mechanism is enabled for all datasources when a metrics extension is present, and metrics for the Agroal extension are enabled.

To disable metrics for a particular data source,
set `quarkus.datasource.jdbc.enable-metrics` to `false`, or apply `quarkus.datasource.<datasource name>.jdbc.enable-metrics` for a named datasource.
To disable metrics for a particular datasource, set `quarkus.datasource.jdbc.enable-metrics` to `false`, or apply `quarkus.datasource.<datasource name>.jdbc.enable-metrics` for a named datasource.
This disables collecting the metrics and exposing them in the `/q/metrics` endpoint if the mechanism to collect them is disabled.

Conversely, setting `quarkus.datasource.jdbc.enable-metrics` to `true`, or `quarkus.datasource.<datasource name>.jdbc.enable-metrics` for a named datasource explicitly enables metrics collection even if a metrics extension is not in use.
Expand All @@ -641,10 +614,11 @@ If the metrics collection for this datasource is disabled, all values result in

To use tracing with a datasource, you need to add the xref:opentelemetry-tracing.adoc[`quarkus-opentelemetry`] extension to your project.

You don't need to declare a different driver because you need tracing. If you use a JDBC driver, you need to follow the instructions in the OpenTelemetry extension xref:opentelemetry-tracing.adoc#jdbc[here].
You do not need to declare a different driver to enable tracing.
If you use a JDBC driver, you need to follow xref:opentelemetry-tracing.adoc#jdbc[the instructions in the OpenTelemetry extension].

Even with all the tracing infrastructure in place the datasource tracing is not enabled by default, and you need to enable it by setting this property:
[source, properties]
Even with all the tracing infrastructure in place, the datasource tracing is not enabled by default, and you need to enable it by setting this property:
[source,properties]
----
# enable tracing
quarkus.datasource.jdbc.telemetry=true
Expand Down Expand Up @@ -677,7 +651,6 @@ Some databases like H2 and Derby are commonly used in the _embedded mode_ as a f
The recommended approach is to use the real database you intend to use in production, especially when xref:databases-dev-services.adoc[Dev Services provide a zero-config database for testing], and running tests against a container is relatively quick and produces expected results on an actual environment.
However, it is also possible to use JVM-powered databases for scenarios when the ability to run simple integration tests is required.


==== Support and limitations

Embedded databases (H2 and Derby) work in JVM mode.
Expand Down

0 comments on commit 18ea2b3

Please sign in to comment.