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