Skip to content

Commit

Permalink
Merge pull request #36179 from MichalMaler/Transaction-Storing-to-a-d…
Browse files Browse the repository at this point in the history
…atabase-update

Update to the JDBCStore section of the Transaction guide
  • Loading branch information
Ladicek authored Oct 17, 2023
2 parents c2a9958 + 6dabad6 commit 0a8efce
Showing 1 changed file with 29 additions and 24 deletions.
53 changes: 29 additions & 24 deletions docs/src/main/asciidoc/transaction.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,19 @@ This guide is maintained in the main Quarkus repository
and pull requests should be submitted there:
https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc
////
= Using Transactions in Quarkus
= Using transactions in Quarkus
include::_attributes.adoc[]
:categories: data
:summary: Quarkus comes with a Transaction Manager and uses it to coordinate and expose transactions to your applications. Each extension dealing with persistence will integrate with it for you, and you will explicitly interact with transactions via CDI. This guide will walk you through all that.
:diataxis-type: reference
:categories: data,getting-started
:topics: data,jpa,jta,transactions,narayana
:extensions: io.quarkus:quarkus-narayana-jta

Quarkus comes with a Transaction Manager and uses it to coordinate and expose transactions to your applications.
Each extension dealing with persistence will integrate with it for you.
And you will explicitly interact with transactions via CDI.
This guide will walk you through all that.
The `quarkus-narayana-jta` extension provides a Transaction Manager that coordinates and expose transactions to your applications as described in the link: https://jakarta.ee/specifications/transactions/[Jakarta Transactions] specification, formerly known as Java Transaction API (JTA).

When discussing Quarkus transactions, this guide refers to Jakarta Transactions transaction style and uses only the term _transaction_ to address them.

Also, Quarkus does not support distributed transactions.
This means that models that propagate transaction context, such as link:https://download.oracle.com/otndocs/jcp/7309-jts-1.0-spec-oth-JSpec/[Java Transaction Service] (JTS), REST-AT, WS-Atomic Transaction, and others, are not supported by the `narayana-jta` extension.

== Setting it up

Expand Down Expand Up @@ -122,7 +124,7 @@ public class SantaClausService {
<2> Programmatically decide to set the transaction for rollback.


=== Transaction Configuration
=== Transaction configuration

Advanced configuration of the transaction is possible with the use of the `@TransactionConfiguration` annotation that is set in addition to the standard `@Transactional` annotation on your entry method or at the class level.

Expand All @@ -139,8 +141,8 @@ The configuration defined on a method takes precedence over the configuration de
If your `@Transactional`-annotated method returns a reactive value, such as:

- `CompletionStage` (from the JDK)
- `Publisher` (from Reactive-Streams)
- Any type which can be converted to one of the two previous types using Reactive Type Converters
- `Publisher` (from Reactive-Streams)
- Any type that can be converted to one of the two previous types using Reactive Type Converters

then the behaviour is a bit different, because the transaction will not be terminated until the
returned reactive value is terminated. In effect, the returned reactive value will be listened to
Expand All @@ -153,7 +155,7 @@ work is really done, and not just until the reactive method returns.
If you need to propagate your transaction context across your reactive pipeline, please see the
xref:context-propagation.adoc[Context Propagation guide].

=== Programmatic Approach
=== Programmatic approach

You can use static methods on `QuarkusTransaction` to define transaction boundaries. This provides two different options,
a functional approach that allows you to run a lambda within the scope of a transaction, or by using explicit `begin`,
Expand Down Expand Up @@ -367,37 +369,41 @@ which is a CDI bean and can be ``@Inject``ed.
[[jdbcstore]]
== Configure storing of Quarkus transaction logs in a database

In cloud environments where persistent storage is not available, such as when application containers are unable to use persistent volumes, you can configure the transaction management to store transaction logs in a database by using a JDBC datasource.

IMPORTANT: While there are several benefits to using a database to store transaction logs, you might notice a reduction in performance compared with using the file system to store the logs.
In cloud environments where persistent storage is not available, such as when application containers are unable to use persistent volumes, you can configure the transaction management to store transaction logs in a database by using a Java Database Connectivity (JDBC) datasource.

Quarkus allows the following JDBC-specific configuration of the object store included in `quarkus.transaction-manager.object-store.<property>` properties, where <property> can be:
However, in cloud-native apps, using a database to store transaction logs has additional requirements.
The `narayana-jta` extension, which manages these transactions, requires stable storage, a unique reusable node identifier, and a steady IP address to work correctly.
While the JDBC object store provides a stable storage, users must still plan how to meet the other two requirements.

Quarkus, after you evaluate whether using a database to store transaction logs is right for you, allows the following JDBC-specific configuration of the object store included in `quarkus.transaction-manager.object-store._<property>_` properties, where _<property>_ can be:

* `type` (_string_): Configure this property to `jdbc` to enable usage of a Quarkus JDBC datasource for transaction logging.
* `type` (_string_): Configure this property to `jdbc` to enable usage of a Quarkus JDBC datasource for storing transaction logs.
The default value is `file-system`.

* `datasource` (_string_): Specify the name of the datasource for the transaction log storage.
If no value is provided for the `datasource` property, Quarkus uses the xref:datasource.adoc#configure-datasources[default datasource].

* `create-table` (_boolean_): When set to `true`, the transaction log table gets automatically created if it does not already exist.
The default value is `false`.

* `drop-table` (_boolean_): When set to `true`, the tables are dropped on startup if they already exist.
The default value is `false`.

* `table-prefix` (string): Specify the prefix for a related table name.
The default value is `quarkus_`.

// This paragraph will differ from the RHBQ docs in the future since it is not supported in the product yet.
Additional information:
For more configuration information, see the *Narayana JTA - Transaction manager* section of the Quarkus xref:all-config.adoc[All configuration options] reference.

* You can manually create the transaction log table during the initial setup by setting the `create-table` property to `true`.
.Additional information:

* Create the transaction log table during the initial setup by setting the `create-table` property to `true`.

* JDBC datasources and ActiveMQ Artemis allow the enlistment and automatically register the `XAResourceRecovery`.

** JDBC datasources is part of `quarkus-agroal`, and it needs to use `quarkus.datasource.jdbc.transactions=XA`.
** ActiveMQ Artemis is part of `quarkus-pooled-jms`, and it needs to use `quarkus.pooled-jms.transaction=XA`.
+
For more information, see link:https://issues.redhat.com/browse/CEQ-4878[CEQ-4878].

* If your application employs eXtended Architecture (XA) transactions, enable the transaction crash recovery feature by using `quarkus.transaction-manager.enable-recovery=true`, to safeguard your data in the event of application crashes or failures. The default value for XA Recovery is `false`.
* To ensure data integrity in case of application crashes or failures, enable the transaction crash recovery with the `quarkus.transaction-manager.enable-recovery=true` configuration.

[NOTE]
====
Expand All @@ -410,7 +416,6 @@ quarkus.datasource.TX_LOG.jdbc.transactions=disabled
This example uses TX_LOG as the datasource name.
====


== Why always having a transaction manager?

Does it work everywhere I want to?::
Expand Down Expand Up @@ -447,6 +452,6 @@ Transactions are also about JMS and other database access, so one API makes more
It's a mess because I don't know if my Jakarta Persistence persistence unit is using `JTA` or `Resource-level` Transaction::

It's not a mess in Quarkus :)
Resource-level was introduced to support Jakarta Persistence in a non managed environment.
Resource-level was introduced to support Jakarta Persistence in a non-managed environment.
But Quarkus is both lean and a managed environment, so we can safely always assume we are in JTA mode.
The end result is that the difficulties of running Hibernate ORM + CDI + a transaction manager in Java SE mode are solved by Quarkus.

0 comments on commit 0a8efce

Please sign in to comment.