001/*
002 * Copyright 2002-2019 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.transaction.reactive;
018
019import reactor.core.publisher.Mono;
020
021/**
022 * Interface for reactive transaction synchronization callbacks.
023 * Supported by {@link AbstractReactiveTransactionManager}.
024 *
025 * <p>TransactionSynchronization implementations can implement the
026 * {@link org.springframework.core.Ordered} interface to influence their execution order.
027 * A synchronization that does not implement the {@link org.springframework.core.Ordered}
028 * interface is appended to the end of the synchronization chain.
029 *
030 * <p>System synchronizations performed by Spring itself use specific order values,
031 * allowing for fine-grained interaction with their execution order (if necessary).
032 *
033 * @author Mark Paluch
034 * @author Juergen Hoeller
035 * @since 5.2
036 * @see TransactionSynchronizationManager
037 * @see AbstractReactiveTransactionManager
038 */
039public interface TransactionSynchronization {
040
041        /** Completion status in case of proper commit. */
042        int STATUS_COMMITTED = 0;
043
044        /** Completion status in case of proper rollback. */
045        int STATUS_ROLLED_BACK = 1;
046
047        /** Completion status in case of heuristic mixed completion or system errors. */
048        int STATUS_UNKNOWN = 2;
049
050
051        /**
052         * Suspend this synchronization.
053         * Supposed to unbind resources from TransactionSynchronizationManager if managing any.
054         * @see TransactionSynchronizationManager#unbindResource
055         */
056        default Mono<Void> suspend() {
057                return Mono.empty();
058        }
059
060        /**
061         * Resume this synchronization.
062         * Supposed to rebind resources to TransactionSynchronizationManager if managing any.
063         * @see TransactionSynchronizationManager#bindResource
064         */
065        default Mono<Void> resume() {
066                return Mono.empty();
067        }
068
069        /**
070         * Invoked before transaction commit (before "beforeCompletion").
071         * <p>This callback does <i>not</i> mean that the transaction will actually be committed.
072         * A rollback decision can still occur after this method has been called. This callback
073         * is rather meant to perform work that's only relevant if a commit still has a chance
074         * to happen, such as flushing SQL statements to the database.
075         * <p>Note that exceptions will get propagated to the commit caller and cause a
076         * rollback of the transaction.
077         * @param readOnly whether the transaction is defined as read-only transaction
078         * @throws RuntimeException in case of errors; will be <b>propagated to the caller</b>
079         * (note: do not throw TransactionException subclasses here!)
080         * @see #beforeCompletion
081         */
082        default Mono<Void> beforeCommit(boolean readOnly) {
083                return Mono.empty();
084        }
085
086        /**
087         * Invoked before transaction commit/rollback.
088         * Can perform resource cleanup <i>before</i> transaction completion.
089         * <p>This method will be invoked after {@code beforeCommit}, even when
090         * {@code beforeCommit} threw an exception. This callback allows for
091         * closing resources before transaction completion, for any outcome.
092         * @throws RuntimeException in case of errors; will be <b>logged but not propagated</b>
093         * (note: do not throw TransactionException subclasses here!)
094         * @see #beforeCommit
095         * @see #afterCompletion
096         */
097        default Mono<Void> beforeCompletion() {
098                return Mono.empty();
099        }
100
101        /**
102         * Invoked after transaction commit. Can perform further operations right
103         * <i>after</i> the main transaction has <i>successfully</i> committed.
104         * <p>Can e.g. commit further operations that are supposed to follow on a successful
105         * commit of the main transaction, like confirmation messages or emails.
106         * <p><b>NOTE:</b> The transaction will have been committed already, but the
107         * transactional resources might still be active and accessible. As a consequence,
108         * any data access code triggered at this point will still "participate" in the
109         * original transaction, allowing to perform some cleanup (with no commit following
110         * anymore!), unless it explicitly declares that it needs to run in a separate
111         * transaction. Hence: <b>Use {@code PROPAGATION_REQUIRES_NEW} for any
112         * transactional operation that is called from here.</b>
113         * @throws RuntimeException in case of errors; will be <b>propagated to the caller</b>
114         * (note: do not throw TransactionException subclasses here!)
115         */
116        default Mono<Void> afterCommit() {
117                return Mono.empty();
118        }
119
120        /**
121         * Invoked after transaction commit/rollback.
122         * Can perform resource cleanup <i>after</i> transaction completion.
123         * <p><b>NOTE:</b> The transaction will have been committed or rolled back already,
124         * but the transactional resources might still be active and accessible. As a
125         * consequence, any data access code triggered at this point will still "participate"
126         * in the original transaction, allowing to perform some cleanup (with no commit
127         * following anymore!), unless it explicitly declares that it needs to run in a
128         * separate transaction. Hence: <b>Use {@code PROPAGATION_REQUIRES_NEW}
129         * for any transactional operation that is called from here.</b>
130         * @param status completion status according to the {@code STATUS_*} constants
131         * @throws RuntimeException in case of errors; will be <b>logged but not propagated</b>
132         * (note: do not throw TransactionException subclasses here!)
133         * @see #STATUS_COMMITTED
134         * @see #STATUS_ROLLED_BACK
135         * @see #STATUS_UNKNOWN
136         * @see #beforeCompletion
137         */
138        default Mono<Void> afterCompletion(int status) {
139                return Mono.empty();
140        }
141
142}