ActiveTxContext.java

/*
 * SPDX-FileCopyrightText: 2026 kaumei.io
 * SPDX-License-Identifier: Apache-2.0
 */
package io.kaumei.jdbc.tx.internal;

import org.jspecify.annotations.Nullable;

import static java.util.Objects.requireNonNull;

class ActiveTxContext {

    private final ThreadLocal<@Nullable ThreadTxContext> context = new ThreadLocal<>();

    boolean hasCurrent() {
        return context.get() != null;
    }

    void restore(@Nullable ThreadTxContext value) {
        if (context.get() != null) {
            throw new IllegalStateException(
                    "Cannot restore transaction context while another transaction is active.");
        } else if (value != null) {
            context.set(value);
        }
    }

    void activate(ThreadTxContext value) {
        if (context.get() != null) {
            throw new IllegalStateException(
                    "Cannot activate transaction context while another transaction is active.");
        }
        context.set(requireNonNull(value, "value"));
    }

    /**
     * Remove value from thread and return it
     */
    @Nullable ThreadTxContext suspend() {
        var suspended = context.get();
        context.remove();
        return suspended;
    }

    @Nullable ThreadTxContext currentOpt() {
        return context.get();
    }

    ThreadTxContext current() {
        var ctx = context.get();
        if (ctx == null) {
            throw new IllegalStateException("No active transaction.");
        }
        return ctx;
    }

    void requireNoCurrent() {
        if (context.get() != null) {
            throw new IllegalStateException("Active transaction exists.");
        }
    }
}