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