001/*
002 * Copyright 2002-2018 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.interceptor;
018
019import org.springframework.lang.Nullable;
020import org.springframework.transaction.support.DefaultTransactionDefinition;
021import org.springframework.util.StringUtils;
022
023/**
024 * Spring's common transaction attribute implementation.
025 * Rolls back on runtime, but not checked, exceptions by default.
026 *
027 * @author Rod Johnson
028 * @author Juergen Hoeller
029 * @since 16.03.2003
030 */
031@SuppressWarnings("serial")
032public class DefaultTransactionAttribute extends DefaultTransactionDefinition implements TransactionAttribute {
033
034        @Nullable
035        private String qualifier;
036
037        @Nullable
038        private String descriptor;
039
040
041        /**
042         * Create a new DefaultTransactionAttribute, with default settings.
043         * Can be modified through bean property setters.
044         * @see #setPropagationBehavior
045         * @see #setIsolationLevel
046         * @see #setTimeout
047         * @see #setReadOnly
048         * @see #setName
049         */
050        public DefaultTransactionAttribute() {
051                super();
052        }
053
054        /**
055         * Copy constructor. Definition can be modified through bean property setters.
056         * @see #setPropagationBehavior
057         * @see #setIsolationLevel
058         * @see #setTimeout
059         * @see #setReadOnly
060         * @see #setName
061         */
062        public DefaultTransactionAttribute(TransactionAttribute other) {
063                super(other);
064        }
065
066        /**
067         * Create a new DefaultTransactionAttribute with the given
068         * propagation behavior. Can be modified through bean property setters.
069         * @param propagationBehavior one of the propagation constants in the
070         * TransactionDefinition interface
071         * @see #setIsolationLevel
072         * @see #setTimeout
073         * @see #setReadOnly
074         */
075        public DefaultTransactionAttribute(int propagationBehavior) {
076                super(propagationBehavior);
077        }
078
079
080        /**
081         * Associate a qualifier value with this transaction attribute.
082         * <p>This may be used for choosing a corresponding transaction manager
083         * to process this specific transaction.
084         * @since 3.0
085         */
086        public void setQualifier(@Nullable String qualifier) {
087                this.qualifier = qualifier;
088        }
089
090        /**
091         * Return a qualifier value associated with this transaction attribute.
092         * @since 3.0
093         */
094        @Override
095        @Nullable
096        public String getQualifier() {
097                return this.qualifier;
098        }
099
100        /**
101         * Set a descriptor for this transaction attribute,
102         * e.g. indicating where the attribute is applying.
103         * @since 4.3.4
104         */
105        public void setDescriptor(@Nullable String descriptor) {
106                this.descriptor = descriptor;
107        }
108
109        /**
110         * Return a descriptor for this transaction attribute,
111         * or {@code null} if none.
112         * @since 4.3.4
113         */
114        @Nullable
115        public String getDescriptor() {
116                return this.descriptor;
117        }
118
119        /**
120         * The default behavior is as with EJB: rollback on unchecked exception
121         * ({@link RuntimeException}), assuming an unexpected outcome outside of any
122         * business rules. Additionally, we also attempt to rollback on {@link Error} which
123         * is clearly an unexpected outcome as well. By contrast, a checked exception is
124         * considered a business exception and therefore a regular expected outcome of the
125         * transactional business method, i.e. a kind of alternative return value which
126         * still allows for regular completion of resource operations.
127         * <p>This is largely consistent with TransactionTemplate's default behavior,
128         * except that TransactionTemplate also rolls back on undeclared checked exceptions
129         * (a corner case). For declarative transactions, we expect checked exceptions to be
130         * intentionally declared as business exceptions, leading to a commit by default.
131         * @see org.springframework.transaction.support.TransactionTemplate#execute
132         */
133        @Override
134        public boolean rollbackOn(Throwable ex) {
135                return (ex instanceof RuntimeException || ex instanceof Error);
136        }
137
138
139        /**
140         * Return an identifying description for this transaction attribute.
141         * <p>Available to subclasses, for inclusion in their {@code toString()} result.
142         */
143        protected final StringBuilder getAttributeDescription() {
144                StringBuilder result = getDefinitionDescription();
145                if (StringUtils.hasText(this.qualifier)) {
146                        result.append("; '").append(this.qualifier).append("'");
147                }
148                return result;
149        }
150
151}