001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.spring.transaction;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    
020    import org.aopalliance.intercept.MethodInvocation;
021    
022    import org.springframework.transaction.PlatformTransactionManager;
023    import org.springframework.transaction.TransactionStatus;
024    import org.springframework.transaction.TransactionSystemException;
025    import org.springframework.transaction.interceptor.TransactionAttribute;
026    
027    /**
028     * @author Michael C. Han
029     * @author Shuyang Zhou
030     */
031    public class DefaultTransactionExecutor extends BaseTransactionExecutor {
032    
033            @Override
034            public Object execute(
035                            PlatformTransactionManager platformTransactionManager,
036                            TransactionAttribute transactionAttribute,
037                            MethodInvocation methodInvocation)
038                    throws Throwable {
039    
040                    TransactionStatus transactionStatus =
041                            platformTransactionManager.getTransaction(transactionAttribute);
042    
043                    boolean newTransaction = transactionStatus.isNewTransaction();
044    
045                    if (newTransaction) {
046                            fireTransactionCreatedEvent(
047                                    transactionAttribute, transactionStatus);
048                    }
049    
050                    Object returnValue = null;
051    
052                    try {
053                            returnValue = methodInvocation.proceed();
054                    }
055                    catch (Throwable throwable) {
056                            processThrowable(
057                                    platformTransactionManager, throwable, transactionAttribute,
058                                    transactionStatus);
059                    }
060    
061                    processCommit(
062                            platformTransactionManager, transactionAttribute,
063                            transactionStatus);
064    
065                    return returnValue;
066            }
067    
068            protected void processCommit(
069                    PlatformTransactionManager platformTransactionManager,
070                    TransactionAttribute transactionAttribute,
071                    TransactionStatus transactionStatus) {
072    
073                    Throwable throwable = null;
074    
075                    try {
076                            platformTransactionManager.commit(transactionStatus);
077                    }
078                    catch (TransactionSystemException tse) {
079                            _log.error(
080                                    "Application exception overridden by commit exception", tse);
081    
082                            throwable = tse;
083    
084                            throw tse;
085                    }
086                    catch (RuntimeException re) {
087                            _log.error(
088                                    "Application exception overridden by commit exception", re);
089    
090                            throwable = re;
091    
092                            throw re;
093                    }
094                    catch (Error e) {
095                            _log.error("Application exception overridden by commit error", e);
096    
097                            throwable = e;
098    
099                            throw e;
100                    }
101                    finally {
102                            if (transactionStatus.isNewTransaction()) {
103                                    if (throwable != null) {
104                                            fireTransactionRollbackedEvent(
105                                                    transactionAttribute, transactionStatus, throwable);
106                                    }
107                                    else {
108                                            fireTransactionCommittedEvent(
109                                                    transactionAttribute, transactionStatus);
110                                    }
111                            }
112                    }
113            }
114    
115            protected void processThrowable(
116                            PlatformTransactionManager platformTransactionManager,
117                            Throwable throwable, TransactionAttribute transactionAttribute,
118                            TransactionStatus transactionStatus)
119                    throws Throwable {
120    
121                    if (transactionAttribute.rollbackOn(throwable)) {
122                            try {
123                                    platformTransactionManager.rollback(transactionStatus);
124                            }
125                            catch (TransactionSystemException tse) {
126                                    _log.error(
127                                            "Application exception overridden by rollback exception",
128                                            tse);
129    
130                                    throw tse;
131                            }
132                            catch (RuntimeException re) {
133                                    _log.error(
134                                            "Application exception overridden by rollback exception",
135                                            re);
136    
137                                    throw re;
138                            }
139                            catch (Error e) {
140                                    _log.error(
141                                            "Application exception overridden by rollback error", e);
142    
143                                    throw e;
144                            }
145                            finally {
146                                    if (transactionStatus.isNewTransaction()) {
147                                            fireTransactionRollbackedEvent(
148                                                    transactionAttribute, transactionStatus, throwable);
149                                    }
150                            }
151                    }
152                    else {
153                            processCommit(
154                                    platformTransactionManager, transactionAttribute,
155                                    transactionStatus);
156                    }
157    
158                    throw throwable;
159            }
160    
161            private static final Log _log = LogFactoryUtil.getLog(
162                    DefaultTransactionExecutor.class);
163    
164    }