001
014
015 package com.liferay.portal.spring.transaction;
016
017 import com.liferay.portal.cache.transactional.TransactionalPortalCacheHelper;
018 import com.liferay.portal.kernel.dao.orm.EntityCacheUtil;
019 import com.liferay.portal.kernel.dao.orm.FinderCacheUtil;
020 import com.liferay.portal.spring.hibernate.LastSessionRecorderUtil;
021
022 import org.aopalliance.intercept.MethodInvocation;
023
024 import org.springframework.transaction.PlatformTransactionManager;
025 import org.springframework.transaction.TransactionStatus;
026 import org.springframework.transaction.interceptor.TransactionAttribute;
027 import org.springframework.transaction.support.CallbackPreferringPlatformTransactionManager;
028 import org.springframework.transaction.support.TransactionCallback;
029
030
034 public class CallbackPreferringTransactionExecutor
035 extends BaseTransactionExecutor {
036
037 public Object execute(
038 PlatformTransactionManager platformTransactionManager,
039 TransactionAttribute transactionAttribute,
040 MethodInvocation methodInvocation)
041 throws Throwable {
042
043 CallbackPreferringPlatformTransactionManager
044 callbackPreferringPlatformTransactionManager =
045 (CallbackPreferringPlatformTransactionManager)
046 platformTransactionManager;
047
048 Object result = callbackPreferringPlatformTransactionManager.execute(
049 transactionAttribute,
050 new CallbackPreferringTransactionCallback(
051 transactionAttribute, methodInvocation));
052
053 if (result instanceof ThrowableHolder) {
054 ThrowableHolder throwableHolder = (ThrowableHolder)result;
055
056 throw throwableHolder.getThrowable();
057 }
058
059 return result;
060 }
061
062 protected static class ThrowableHolder {
063
064 public ThrowableHolder(Throwable throwable) {
065 _throwable = throwable;
066 }
067
068 public Throwable getThrowable() {
069 return _throwable;
070 }
071
072 private Throwable _throwable;
073
074 }
075
076 private class CallbackPreferringTransactionCallback
077 implements TransactionCallback<Object> {
078
079 private CallbackPreferringTransactionCallback(
080 TransactionAttribute transactionAttribute,
081 MethodInvocation methodInvocation) {
082
083 _transactionAttribute = transactionAttribute;
084 _methodInvocation = methodInvocation;
085 }
086
087 public Object doInTransaction(TransactionStatus transactionStatus) {
088 boolean newTransaction = transactionStatus.isNewTransaction();
089
090 if (newTransaction) {
091 TransactionalPortalCacheHelper.begin();
092
093 TransactionCommitCallbackUtil.pushCallbackList();
094 }
095
096 boolean rollback = false;
097
098 try {
099 if (newTransaction) {
100 LastSessionRecorderUtil.syncLastSessionState();
101 }
102
103 return _methodInvocation.proceed();
104 }
105 catch (Throwable throwable) {
106 if (_transactionAttribute.rollbackOn(throwable)) {
107 if (newTransaction) {
108 TransactionalPortalCacheHelper.rollback();
109
110 TransactionCommitCallbackUtil.popCallbackList();
111
112 EntityCacheUtil.clearLocalCache();
113 FinderCacheUtil.clearLocalCache();
114
115 rollback = true;
116 }
117
118 if (throwable instanceof RuntimeException) {
119 throw (RuntimeException)throwable;
120 }
121 else {
122 throw new RuntimeException(throwable);
123 }
124 }
125 else {
126 return new ThrowableHolder(throwable);
127 }
128 }
129 finally {
130 if (newTransaction && !rollback) {
131 TransactionalPortalCacheHelper.commit();
132
133 invokeCallbacks();
134 }
135 }
136 }
137
138 private MethodInvocation _methodInvocation;
139 private TransactionAttribute _transactionAttribute;
140
141 }
142
143 }