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 java.util.LinkedHashMap;
020import java.util.Map;
021import java.util.Set;
022import java.util.UUID;
023
024import org.springframework.lang.Nullable;
025import org.springframework.util.StringUtils;
026
027/**
028 * Mutable transaction context that encapsulates transactional synchronizations and
029 * resources in the scope of a single transaction. Transaction context is typically
030 * held by an outer {@link TransactionContextHolder} or referenced directly within
031 * from the subscriber context.
032 *
033 * @author Mark Paluch
034 * @author Juergen Hoeller
035 * @since 5.2
036 * @see TransactionContextManager
037 * @see reactor.util.context.Context
038 */
039public class TransactionContext {
040
041        private final @Nullable TransactionContext parent;
042
043        private final UUID contextId = UUID.randomUUID();
044
045        private final Map<Object, Object> resources = new LinkedHashMap<>();
046
047        @Nullable
048        private Set<TransactionSynchronization> synchronizations;
049
050        private volatile @Nullable String currentTransactionName;
051
052        private volatile boolean currentTransactionReadOnly;
053
054        private volatile @Nullable Integer currentTransactionIsolationLevel;
055
056        private volatile boolean actualTransactionActive;
057
058
059        TransactionContext() {
060                this(null);
061        }
062
063        TransactionContext(@Nullable TransactionContext parent) {
064                this.parent = parent;
065        }
066
067
068        @Nullable
069        public TransactionContext getParent() {
070                return this.parent;
071        }
072
073        public String getName() {
074                if (StringUtils.hasText(this.currentTransactionName)) {
075                        return this.contextId + ": " + this.currentTransactionName;
076                }
077                return this.contextId.toString();
078        }
079
080        public UUID getContextId() {
081                return this.contextId;
082        }
083
084        public Map<Object, Object> getResources() {
085                return this.resources;
086        }
087
088        public void setSynchronizations(@Nullable Set<TransactionSynchronization> synchronizations) {
089                this.synchronizations = synchronizations;
090        }
091
092        @Nullable
093        public Set<TransactionSynchronization> getSynchronizations() {
094                return this.synchronizations;
095        }
096
097        public void setCurrentTransactionName(@Nullable String currentTransactionName) {
098                this.currentTransactionName = currentTransactionName;
099        }
100
101        @Nullable
102        public String getCurrentTransactionName() {
103                return this.currentTransactionName;
104        }
105
106        public void setCurrentTransactionReadOnly(boolean currentTransactionReadOnly) {
107                this.currentTransactionReadOnly = currentTransactionReadOnly;
108        }
109
110        public boolean isCurrentTransactionReadOnly() {
111                return this.currentTransactionReadOnly;
112        }
113
114        public void setCurrentTransactionIsolationLevel(@Nullable Integer currentTransactionIsolationLevel) {
115                this.currentTransactionIsolationLevel = currentTransactionIsolationLevel;
116        }
117
118        @Nullable
119        public Integer getCurrentTransactionIsolationLevel() {
120                return this.currentTransactionIsolationLevel;
121        }
122
123        public void setActualTransactionActive(boolean actualTransactionActive) {
124                this.actualTransactionActive = actualTransactionActive;
125        }
126
127        public boolean isActualTransactionActive() {
128                return this.actualTransactionActive;
129        }
130
131
132        public void clear() {
133                this.synchronizations = null;
134                this.currentTransactionName = null;
135                this.currentTransactionReadOnly = false;
136                this.currentTransactionIsolationLevel = null;
137                this.actualTransactionActive = false;
138        }
139
140}