|
10 | 10 |
|
11 | 11 | import org.hibernate.resource.transaction.spi.TransactionStatus;
|
12 | 12 |
|
| 13 | +import java.util.function.Consumer; |
| 14 | + |
| 15 | +import static org.hibernate.resource.transaction.backend.jta.internal.StatusTranslator.translate; |
| 16 | + |
13 | 17 | /**
|
14 | 18 | * Represents a resource-local transaction, where <em>resource-local</em> is interpreted
|
15 | 19 | * by Hibernate to mean any transaction under the control of Hibernate. That is to say,
|
|
38 | 42 | *
|
39 | 43 | * @author Anton van Straaten
|
40 | 44 | * @author Steve Ebersole
|
| 45 | + * @author Gavin King |
41 | 46 | *
|
42 | 47 | * @see Session#beginTransaction()
|
43 | 48 | */
|
44 | 49 | public interface Transaction extends EntityTransaction {
|
45 | 50 | /**
|
46 | 51 | * Get the current {@linkplain TransactionStatus status} of this transaction.
|
| 52 | + * |
| 53 | + * @apiNote {@link TransactionStatus} belongs to an SPI package, and so this |
| 54 | + * operation is a (fairly harmless) layer-breaker. Prefer the use |
| 55 | + * of {@link #isActive}, {@link #isComplete}, {@link #wasStarted}, |
| 56 | + * {@link #wasSuccessful}, {@link #wasFailure}, or |
| 57 | + * {@link #isInCompletionProcess} according to need. |
| 58 | + * |
47 | 59 | */
|
48 | 60 | TransactionStatus getStatus();
|
49 | 61 |
|
50 | 62 | /**
|
51 |
| - * Register a user {@link Synchronization synchronization callback} for this transaction. |
| 63 | + * Is this transaction still active? |
| 64 | + * <p> |
| 65 | + * A transaction which has been {@linkplain #markRollbackOnly marked for rollback} |
| 66 | + * is still considered active, and is still able to perform work. To determine if |
| 67 | + * a transaction has been marked for rollback, call {@link #getRollbackOnly()}. |
| 68 | + * |
| 69 | + * @return {@code true} if the {@linkplain #getStatus status} |
| 70 | + * is {@link TransactionStatus#ACTIVE} or |
| 71 | + * {@link TransactionStatus#MARKED_ROLLBACK} |
| 72 | + */ |
| 73 | + default boolean isActive() { |
| 74 | + return switch (getStatus()) { |
| 75 | + case ACTIVE, MARKED_ROLLBACK -> true; |
| 76 | + default -> false; |
| 77 | + }; |
| 78 | + } |
| 79 | + |
| 80 | + /** |
| 81 | + * Is this transaction currently in the completion process? |
| 82 | + * <p> |
| 83 | + * Note that a {@link Synchronization} is called <em>before</em> and <em>after</em> |
| 84 | + * the completion process. Therefore, this state is not usually observable to the |
| 85 | + * client program logic. |
| 86 | + * |
| 87 | + * @return {@code true} if the {@linkplain #getStatus status} |
| 88 | + * is {@link TransactionStatus#COMMITTING} or |
| 89 | + * {@link TransactionStatus#ROLLING_BACK} |
| 90 | + * |
| 91 | + * @since 7.0 |
| 92 | + */ |
| 93 | + @Incubating |
| 94 | + default boolean isInCompletionProcess() { |
| 95 | + return switch (getStatus()) { |
| 96 | + case COMMITTING, ROLLING_BACK -> true; |
| 97 | + default -> false; |
| 98 | + }; |
| 99 | + } |
| 100 | + |
| 101 | + /** |
| 102 | + * Is this transaction complete? |
| 103 | + * |
| 104 | + * @return {@code true} if the {@linkplain #getStatus status} |
| 105 | + * is {@link TransactionStatus#COMMITTED}, |
| 106 | + * {@link TransactionStatus#ROLLED_BACK}, |
| 107 | + * {@link TransactionStatus#FAILED_COMMIT}, or |
| 108 | + * {@link TransactionStatus#FAILED_ROLLBACK} |
| 109 | + * |
| 110 | + * @since 7.0 |
| 111 | + */ |
| 112 | + @Incubating |
| 113 | + default boolean isComplete() { |
| 114 | + return switch (getStatus()) { |
| 115 | + case COMMITTED, ROLLED_BACK, FAILED_COMMIT, FAILED_ROLLBACK -> true; |
| 116 | + default -> false; |
| 117 | + }; |
| 118 | + } |
| 119 | + |
| 120 | + /** |
| 121 | + * Was this transaction already started? |
| 122 | + * |
| 123 | + * @return {@code true} if the {@linkplain #getStatus status} is |
| 124 | + * anything other than {@link TransactionStatus#NOT_ACTIVE} |
| 125 | + * |
| 126 | + * @since 7.0 |
| 127 | + */ |
| 128 | + @Incubating |
| 129 | + default boolean wasStarted() { |
| 130 | + return getStatus() != TransactionStatus.NOT_ACTIVE; |
| 131 | + } |
| 132 | + |
| 133 | + /** |
| 134 | + * Was this transaction already successfully committed? |
| 135 | + * |
| 136 | + * @return {@code true} if the {@linkplain #getStatus status} |
| 137 | + * is {@link TransactionStatus#COMMITTED} |
| 138 | + * |
| 139 | + * @since 7.0 |
| 140 | + */ |
| 141 | + @Incubating |
| 142 | + default boolean wasSuccessful() { |
| 143 | + return getStatus() == TransactionStatus.COMMITTED; |
| 144 | + } |
| 145 | + |
| 146 | + /** |
| 147 | + * Was this transaction a failure? Here we consider a successful rollback, |
| 148 | + * a failed commit, or a failed rollback to amount to transaction failure. |
| 149 | + * |
| 150 | + * @return {@code true} if the {@linkplain #getStatus status} |
| 151 | + * is {@link TransactionStatus#ROLLED_BACK}, |
| 152 | + * {@link TransactionStatus#FAILED_COMMIT}, |
| 153 | + * {@link TransactionStatus#FAILED_ROLLBACK} |
| 154 | + * |
| 155 | + * @since 7.0 |
| 156 | + */ |
| 157 | + @Incubating |
| 158 | + default boolean wasFailure() { |
| 159 | + return switch (getStatus()) { |
| 160 | + case ROLLED_BACK, FAILED_COMMIT, FAILED_ROLLBACK -> true; |
| 161 | + default -> false; |
| 162 | + }; |
| 163 | + } |
| 164 | + |
| 165 | + /** |
| 166 | + * Register an action which will be called during the "before completion" phase. |
52 | 167 | *
|
53 |
| - * @param synchronization The {@link Synchronization} callback to register. |
| 168 | + * @since 7.0 |
| 169 | + */ |
| 170 | + @Incubating |
| 171 | + default void runBeforeCompletion(Runnable action) { |
| 172 | + registerSynchronization( new Synchronization() { |
| 173 | + @Override |
| 174 | + public void beforeCompletion() { |
| 175 | + action.run(); |
| 176 | + } |
| 177 | + @Override |
| 178 | + public void afterCompletion(int status) { |
| 179 | + } |
| 180 | + } ); |
| 181 | + } |
| 182 | + |
| 183 | + /** |
| 184 | + * Register an action which will be called during the "after completion" phase. |
54 | 185 | *
|
55 |
| - * @throws HibernateException Indicates a problem registering the synchronization. |
| 186 | + * @since 7.0 |
| 187 | + */ |
| 188 | + @Incubating |
| 189 | + default void runAfterCompletion(Consumer<TransactionStatus> action) { |
| 190 | + registerSynchronization( new Synchronization() { |
| 191 | + @Override |
| 192 | + public void beforeCompletion() { |
| 193 | + } |
| 194 | + @Override |
| 195 | + public void afterCompletion(int status) { |
| 196 | + action.accept( translate( status ) ); |
| 197 | + } |
| 198 | + } ); |
| 199 | + } |
| 200 | + |
| 201 | + /** |
| 202 | + * Register a {@linkplain Synchronization synchronization callback} for this transaction. |
| 203 | + * |
| 204 | + * @param synchronization The {@link Synchronization} callback to register |
| 205 | + * |
| 206 | + * @apiNote {@link Synchronization} is a type defined by JTA, but this operation does |
| 207 | + * not depend on the use of JTA for transaction management. Prefer the use of |
| 208 | + * the methods {@link #runBeforeCompletion} and {@link #runAfterCompletion} |
| 209 | + * for convenience. |
56 | 210 | */
|
57 | 211 | void registerSynchronization(Synchronization synchronization);
|
58 | 212 |
|
59 | 213 | /**
|
60 |
| - * Set the transaction timeout for any transaction started by any subsequent call to |
61 |
| - * {@link #begin} on this instance. |
| 214 | + * Set the transaction timeout for any transaction started by a subsequent call to |
| 215 | + * {@link #begin} on this instance of {@code Transaction}. |
62 | 216 | *
|
63 |
| - * @param seconds The number of seconds before a timeout. |
| 217 | + * @param seconds The number of seconds before a timeout |
64 | 218 | */
|
65 | 219 | void setTimeout(int seconds);
|
66 | 220 |
|
67 | 221 | /**
|
68 |
| - * Retrieve the transaction timeout set for this instance. A negative integer indicates |
69 |
| - * that no timeout has been set. |
| 222 | + * Retrieve the transaction timeout set for this instance. |
| 223 | + * <p> |
| 224 | + * A {@code null} return value indicates that no timeout has been set. |
70 | 225 | *
|
71 |
| - * @return The timeout, in seconds. |
| 226 | + * @return the timeout, in seconds, or {@code null} |
72 | 227 | */
|
73 | 228 | @Nullable Integer getTimeout();
|
74 | 229 |
|
|
0 commit comments