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 org.springframework.lang.Nullable; 020import org.springframework.transaction.ReactiveTransaction; 021import org.springframework.util.Assert; 022 023/** 024 * Default implementation of the {@link ReactiveTransaction} interface, 025 * used by {@link AbstractReactiveTransactionManager}. Based on the concept 026 * of an underlying "transaction object". 027 * 028 * <p>Holds all status information that {@link AbstractReactiveTransactionManager} 029 * needs internally, including a generic transaction object determined by the 030 * concrete transaction manager implementation. 031 * 032 * <p><b>NOTE:</b> This is <i>not</i> intended for use with other ReactiveTransactionManager 033 * implementations, in particular not for mock transaction managers in testing environments. 034 * 035 * @author Mark Paluch 036 * @author Juergen Hoeller 037 * @since 5.2 038 * @see AbstractReactiveTransactionManager 039 * @see #getTransaction 040 */ 041public class GenericReactiveTransaction implements ReactiveTransaction { 042 043 @Nullable 044 private final Object transaction; 045 046 private final boolean newTransaction; 047 048 private final boolean newSynchronization; 049 050 private final boolean readOnly; 051 052 private final boolean debug; 053 054 @Nullable 055 private final Object suspendedResources; 056 057 private boolean rollbackOnly = false; 058 059 private boolean completed = false; 060 061 062 /** 063 * Create a new {@code DefaultReactiveTransactionStatus} instance. 064 * @param transaction underlying transaction object that can hold state 065 * for the internal transaction implementation 066 * @param newTransaction if the transaction is new, otherwise participating 067 * in an existing transaction 068 * @param newSynchronization if a new transaction synchronization has been 069 * opened for the given transaction 070 * @param readOnly whether the transaction is marked as read-only 071 * @param debug should debug logging be enabled for the handling of this transaction? 072 * Caching it in here can prevent repeated calls to ask the logging system whether 073 * debug logging should be enabled. 074 * @param suspendedResources a holder for resources that have been suspended 075 * for this transaction, if any 076 */ 077 public GenericReactiveTransaction( 078 @Nullable Object transaction, boolean newTransaction, boolean newSynchronization, 079 boolean readOnly, boolean debug, @Nullable Object suspendedResources) { 080 081 this.transaction = transaction; 082 this.newTransaction = newTransaction; 083 this.newSynchronization = newSynchronization; 084 this.readOnly = readOnly; 085 this.debug = debug; 086 this.suspendedResources = suspendedResources; 087 } 088 089 090 /** 091 * Return the underlying transaction object. 092 * @throws IllegalStateException if no transaction is active 093 */ 094 public Object getTransaction() { 095 Assert.state(this.transaction != null, "No transaction active"); 096 return this.transaction; 097 } 098 099 /** 100 * Return whether there is an actual transaction active. 101 */ 102 public boolean hasTransaction() { 103 return (this.transaction != null); 104 } 105 106 @Override 107 public boolean isNewTransaction() { 108 return (hasTransaction() && this.newTransaction); 109 } 110 111 /** 112 * Return if a new transaction synchronization has been opened 113 * for this transaction. 114 */ 115 public boolean isNewSynchronization() { 116 return this.newSynchronization; 117 } 118 119 /** 120 * Return if this transaction is defined as read-only transaction. 121 */ 122 public boolean isReadOnly() { 123 return this.readOnly; 124 } 125 126 /** 127 * Return whether the progress of this transaction is debugged. This is used by 128 * {@link AbstractReactiveTransactionManager} as an optimization, to prevent repeated 129 * calls to {@code logger.isDebugEnabled()}. Not really intended for client code. 130 */ 131 public boolean isDebug() { 132 return this.debug; 133 } 134 135 /** 136 * Return the holder for resources that have been suspended for this transaction, 137 * if any. 138 */ 139 @Nullable 140 public Object getSuspendedResources() { 141 return this.suspendedResources; 142 } 143 144 @Override 145 public void setRollbackOnly() { 146 this.rollbackOnly = true; 147 } 148 149 /** 150 * Determine the rollback-only flag via checking this ReactiveTransactionStatus. 151 * <p>Will only return "true" if the application called {@code setRollbackOnly} 152 * on this TransactionStatus object. 153 */ 154 @Override 155 public boolean isRollbackOnly() { 156 return this.rollbackOnly; 157 } 158 159 /** 160 * Mark this transaction as completed, that is, committed or rolled back. 161 */ 162 public void setCompleted() { 163 this.completed = true; 164 } 165 166 @Override 167 public boolean isCompleted() { 168 return this.completed; 169 } 170 171}