quarkusio/quarkus · critical · UnsupportedOperationException

While using @Transactional we need a DatabaseActions Strateg

Error message

While using @Transactional we need a DatabaseActions Strategy. Something was wrong here

What it means

Quarkus's @Transactional interceptor for reactive transactions resolves the ReactiveResource (DatabaseActions strategy) from CDI. The strategy bean is provided by an active reactive-datasource/transaction integration; if the Instance lookup returns null, the CDI container has no strategy bean and the interceptor refuses to proceed, since there is no way to execute transactional work.

Source

Thrown at extensions/reactive-transactions/runtime/src/main/java/io/quarkus/reactive/transaction/runtime/TransactionalInterceptorRequired.java:23

import jakarta.inject.Inject;
import jakarta.interceptor.AroundInvoke;
import jakarta.interceptor.Interceptor;
import jakarta.interceptor.InvocationContext;
import jakarta.transaction.Transactional;

@Transactional(Transactional.TxType.REQUIRED)
@Interceptor
@Priority(Interceptor.Priority.PLATFORM_BEFORE + 300)
public class TransactionalInterceptorRequired extends TransactionalInterceptorBase {

    @Inject
    Instance<ReactiveResource> databaseActionsStrategy;

    @AroundInvoke
    public Object intercept(InvocationContext context) throws Exception {
        ReactiveResource reactiveResource = this.databaseActionsStrategy.get();
        if (reactiveResource == null) {
            throw new UnsupportedOperationException(
                    "While using @Transactional we need a DatabaseActions Strategy. Something was wrong here");
        }
        return doIntercept(context, reactiveResource);
    }

    @Override
    protected void validateTransactionalType(InvocationContext context) {
        // Required is supported
    }
}

View on GitHub (pinned to e1c734241f)

Solutions

  1. Add a reactive datasource extension dependency, e.g. io.quarkus:quarkus-reactive-datasource (or quarkus-hibernate-reactive-panache), so the ReactiveResource strategy bean exists
  2. Configure the datasource (quarkus.datasource.db-kind=postgresql, credentials) so the reactive datasource starts and the strategy bean is produced
  3. If you only need blocking JTA transactions, remove the reactive interceptor usage and ensure quarkus-narayana-transactions is present; check your dependencies for exclusions of quarkus-reactive-datasource runtime modules
  4. Run mvn dependency:tree to confirm the reactive datasource/transaction runtime modules are actually resolved

Example fix

// before (pom.xml)
<dependency>
  <groupId>io.quarkus</groupId>
  <artifactId>quarkus-narayana-transactions</artifactId>
</dependency>
// after
<dependency>
  <groupId>io.quarkus</groupId>
  <artifactId>quarkus-reactive-datasource</artifactId>
</dependency>
Defensive patterns

Strategy: validation

Validate before calling

boolean ok = Class.forName("io.quarkus.reactive.datasource.runtime.ReactiveDatasourceStateConsumer", false,
    Thread.currentThread().getContextClassLoader()).getClass() != null; // build should include reactive datasource
// simpler: assert a reactive db-kind is configured before startup
if (!Arrays.asList("postgresql","mariadb","mysql","mssql","db2","oracle").contains(dbKind)) throw new IllegalStateException("reactive datasource missing");

Prevention

When it happens

Trigger: A method annotated with @Transactional is invoked while no reactive datasource (or other reactive transaction provider) dependency is on the classpath, or the strategy bean failed to be created at build/startup time.

Common situations: Adding quarkus-narayana-transactions or @Transactional without adding a datasource extension; using @Transactional in a module with only quarkus-hibernate-orm-panache removed; dependency exclusions that dropped the reactive datasource runtime; a broken build-time wiring after version upgrades.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/de4d5226294db42e. Report an issue: GitHub.