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.interceptor.TransactionAttribute;
025    
026    /**
027     * @author Michael C. Han
028     * @author Shuyang Zhou
029     */
030    public class DefaultTransactionExecutor
031            extends BaseTransactionExecutor implements TransactionHandler {
032    
033            @Override
034            public void commit(
035                    PlatformTransactionManager platformTransactionManager,
036                    TransactionAttribute transactionAttribute,
037                    TransactionStatus transactionStatus) {
038    
039                    Throwable throwable = null;
040    
041                    try {
042                            platformTransactionManager.commit(transactionStatus);
043                    }
044                    catch (RuntimeException re) {
045                            _log.error(
046                                    "Application exception overridden by commit exception", re);
047    
048                            throwable = re;
049    
050                            throw re;
051                    }
052                    catch (Error e) {
053                            _log.error("Application exception overridden by commit error", e);
054    
055                            throwable = e;
056    
057                            throw e;
058                    }
059                    finally {
060                            if (throwable != null) {
061                                    fireTransactionRollbackedEvent(
062                                            transactionAttribute, transactionStatus, throwable);
063                            }
064                            else {
065                                    fireTransactionCommittedEvent(
066                                            transactionAttribute, transactionStatus);
067                            }
068                    }
069            }
070    
071            @Override
072            public Object execute(
073                            PlatformTransactionManager platformTransactionManager,
074                            TransactionAttribute transactionAttribute,
075                            MethodInvocation methodInvocation)
076                    throws Throwable {
077    
078                    TransactionStatus transactionStatus = start(
079                            platformTransactionManager, transactionAttribute);
080    
081                    Object returnValue = null;
082    
083                    try {
084                            returnValue = methodInvocation.proceed();
085                    }
086                    catch (Throwable throwable) {
087                            rollback(
088                                    platformTransactionManager, throwable, transactionAttribute,
089                                    transactionStatus);
090                    }
091    
092                    commit(
093                            platformTransactionManager, transactionAttribute,
094                            transactionStatus);
095    
096                    return returnValue;
097            }
098    
099            @Override
100            public void rollback(
101                            PlatformTransactionManager platformTransactionManager,
102                            Throwable throwable, TransactionAttribute transactionAttribute,
103                            TransactionStatus transactionStatus)
104                    throws Throwable {
105    
106                    if (transactionAttribute.rollbackOn(throwable)) {
107                            try {
108                                    platformTransactionManager.rollback(transactionStatus);
109                            }
110                            catch (RuntimeException re) {
111                                    re.addSuppressed(throwable);
112    
113                                    _log.error(
114                                            "Application exception overridden by rollback exception",
115                                            re);
116    
117                                    throw re;
118                            }
119                            catch (Error e) {
120                                    e.addSuppressed(throwable);
121    
122                                    _log.error(
123                                            "Application exception overridden by rollback error", e);
124    
125                                    throw e;
126                            }
127                            finally {
128                                    fireTransactionRollbackedEvent(
129                                            transactionAttribute, transactionStatus, throwable);
130                            }
131                    }
132                    else {
133                            commit(
134                                    platformTransactionManager, transactionAttribute,
135                                    transactionStatus);
136                    }
137    
138                    throw throwable;
139            }
140    
141            @Override
142            public TransactionStatus start(
143                    PlatformTransactionManager platformTransactionManager,
144                    TransactionAttribute transactionAttribute) {
145    
146                    TransactionStatus transactionStatus =
147                            platformTransactionManager.getTransaction(transactionAttribute);
148    
149                    fireTransactionCreatedEvent(transactionAttribute, transactionStatus);
150    
151                    return transactionStatus;
152            }
153    
154            private static final Log _log = LogFactoryUtil.getLog(
155                    DefaultTransactionExecutor.class);
156    
157    }