liveBook · Manning

Database transaction

As explained in Quarkus in Action

A transaction is a logical unit of work whose operations are coordinated to satisfy defined consistency and completion guarantees.

A database transaction defines the boundary within which application changes are committed or rolled back. In a Quarkus application using Hibernate, operations that modify the database must run inside a transaction: Hibernate needs it to propagate changes from entities to the database. Quarkus recommends placing transaction boundaries at application entry points, such as REST resource methods. section 7.5.1 section 7.5.3

Quarkus includes a transaction manager when an extension needs one. For transaction use outside that scope, add the quarkus-narayana-jta extension. Choose between declarative boundaries on CDI methods and manual handling with QuarkusTransaction. Distributed transactions in microservices require more care than these data-access patterns cover. section 7.5

For declarative handling, put JTA’s @Transactional on a CDI method that persists, updates, or deletes entities. It normally starts before the method and commits or rolls back when the method finishes, depending on specified exceptions. Its TxType controls participation:

  • REQUIRED, the default, joins an incoming transaction or starts one. section 7.5.1
  • REQUIRES_NEW starts a separate transaction and suspends an existing one; MANDATORY requires an existing transaction. section 7.5.1
  • SUPPORTS joins if possible but can run without a transaction; NOT_SUPPORTED suspends one; NEVER rejects an incoming transaction. section 7.5.1

Persisting an inventory item

A GraphQL register mutation calls carRepository.persist(car) inside an @Transactional method. Its remove mutation finds a car by license-plate number and deletes it under the same annotation. A gRPC stream instead performs persistence inside a callback outside the CDI bean method; QuarkusTransaction.requiringNew().run(...) wraps each persist call so each car has its own transaction. The database operations are marked @Blocking in the gRPC service. section 7.2.2

Use QuarkusTransaction when an annotation does not put the operation inside the needed boundary. Its static API supports explicit begin, commit, and rollback, or wrappers around Runnable and Callable. Wrapper options include joining or requiring a transaction, a timeout, and an exception handler that chooses whether to commit or roll back. Avoid starting or suspending transactions for work that does not need them; doing so adds invocation overhead. section 7.5.2 section 7.5.1

A transaction also governs when pending entity changes reach the database. Hibernate normally flushes gathered SQL before commit or before a query. To check database constraints sooner, call an entity or repository flush method, or persistAndFlush; these methods can throw PersistenceException. Use early flushes sparingly because database communication consumes resources. section 7.5.3

Listing 7.25 Transaction wrappers provided by QuarkusTransaction
QuarkusTransaction.requiringNew().run(() -> {      #1
    // perform operation
});

var txResult = QuarkusTransaction.joiningExisting()
    .timeout(30)
    .exceptionHandler(throwable -> {
        if (throwable instanceof AnyRecoverableException) {
            return TransactionExceptionResult.COMMIT;
        }
        return TransactionExceptionResult.ROLLBACK;
    }).call(() -> {                                     #2
        var result = // perform operation
        return result;
    });

Compare a new transaction around a Runnable with a Callable that joins an existing transaction and configures timeout and exception handling. section 7.5.2

How Quarkus in Action covers it

How deep it goes
Explains boundaries, propagation choices, manual APIs, and flush behavior, but does not develop distributed transaction processing.
Examples
Uses GraphQL inventory mutations, gRPC persistence callbacks, and QuarkusTransaction wrapper code.
What it assumes
Assumes familiarity with CDI methods and repository operations while introducing the relevant JTA annotation and Quarkus transaction APIs.
What you can do after
Apply it via @Transactional or QuarkusTransaction to give database writes an appropriate boundary.
How it connects
Links transactions to CDI, JTA, Hibernate, Panache repositories, and flushing.

Also explained in

Compare how 14 books explain database transaction →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Quarkus in Action. The section links point to the parts of the book it draws on.