001/*
002 * Copyright 2002-2017 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;
018
019import org.springframework.lang.Nullable;
020import org.springframework.util.Assert;
021
022/**
023 * Exception thrown when a general transaction system error is encountered,
024 * like on commit or rollback.
025 *
026 * @author Juergen Hoeller
027 * @since 24.03.2003
028 */
029@SuppressWarnings("serial")
030public class TransactionSystemException extends TransactionException {
031
032        @Nullable
033        private Throwable applicationException;
034
035
036        /**
037         * Constructor for TransactionSystemException.
038         * @param msg the detail message
039         */
040        public TransactionSystemException(String msg) {
041                super(msg);
042        }
043
044        /**
045         * Constructor for TransactionSystemException.
046         * @param msg the detail message
047         * @param cause the root cause from the transaction API in use
048         */
049        public TransactionSystemException(String msg, Throwable cause) {
050                super(msg, cause);
051        }
052
053
054        /**
055         * Set an application exception that was thrown before this transaction exception,
056         * preserving the original exception despite the overriding TransactionSystemException.
057         * @param ex the application exception
058         * @throws IllegalStateException if this TransactionSystemException already holds an
059         * application exception
060         */
061        public void initApplicationException(Throwable ex) {
062                Assert.notNull(ex, "Application exception must not be null");
063                if (this.applicationException != null) {
064                        throw new IllegalStateException("Already holding an application exception: " + this.applicationException);
065                }
066                this.applicationException = ex;
067        }
068
069        /**
070         * Return the application exception that was thrown before this transaction exception,
071         * if any.
072         * @return the application exception, or {@code null} if none set
073         */
074        @Nullable
075        public final Throwable getApplicationException() {
076                return this.applicationException;
077        }
078
079        /**
080         * Return the exception that was the first to be thrown within the failed transaction:
081         * i.e. the application exception, if any, or the TransactionSystemException's own cause.
082         * @return the original exception, or {@code null} if there was none
083         */
084        @Nullable
085        public Throwable getOriginalException() {
086                return (this.applicationException != null ? this.applicationException : getCause());
087        }
088
089        @Override
090        public boolean contains(@Nullable Class<?> exType) {
091                return super.contains(exType) || (exType != null && exType.isInstance(this.applicationException));
092        }
093
094}