001
014
015 package com.liferay.portal.spring.transaction;
016
017 import com.liferay.portal.kernel.transaction.TransactionLifecycleManager;
018
019 import org.aopalliance.intercept.MethodInvocation;
020
021 import org.springframework.transaction.PlatformTransactionManager;
022 import org.springframework.transaction.TransactionStatus;
023 import org.springframework.transaction.support.CallbackPreferringPlatformTransactionManager;
024 import org.springframework.transaction.support.TransactionCallback;
025
026
030 public class CallbackPreferringTransactionExecutor
031 implements TransactionExecutor {
032
033 @Override
034 public Object execute(
035 PlatformTransactionManager platformTransactionManager,
036 TransactionAttributeAdapter transactionAttributeAdapter,
037 MethodInvocation methodInvocation)
038 throws Throwable {
039
040 CallbackPreferringPlatformTransactionManager
041 callbackPreferringPlatformTransactionManager =
042 (CallbackPreferringPlatformTransactionManager)
043 platformTransactionManager;
044
045 try {
046 Object result =
047 callbackPreferringPlatformTransactionManager.execute(
048 transactionAttributeAdapter,
049 createTransactionCallback(
050 transactionAttributeAdapter, methodInvocation));
051
052 if (result instanceof ThrowableHolder) {
053 ThrowableHolder throwableHolder = (ThrowableHolder)result;
054
055 throw throwableHolder.getThrowable();
056 }
057
058 return result;
059 }
060 catch (ThrowableHolderException the) {
061 throw the.getCause();
062 }
063 }
064
065 protected TransactionCallback<Object> createTransactionCallback(
066 TransactionAttributeAdapter transactionAttributeAdapter,
067 MethodInvocation methodInvocation) {
068
069 return new CallbackPreferringTransactionCallback(
070 transactionAttributeAdapter, methodInvocation);
071 }
072
073 protected static class ThrowableHolder {
074
075 public ThrowableHolder(Throwable throwable) {
076 _throwable = throwable;
077 }
078
079 public Throwable getThrowable() {
080 return _throwable;
081 }
082
083 private final Throwable _throwable;
084
085 }
086
087 protected static class ThrowableHolderException extends RuntimeException {
088
089 public ThrowableHolderException(Throwable cause) {
090 super(cause);
091 }
092
093 }
094
095 private class CallbackPreferringTransactionCallback
096 implements TransactionCallback<Object> {
097
098 @Override
099 public Object doInTransaction(TransactionStatus transactionStatus) {
100 TransactionStatusAdapter transactionStatusAdapter =
101 new TransactionStatusAdapter(transactionStatus);
102
103 TransactionLifecycleManager.fireTransactionCreatedEvent(
104 _transactionAttributeAdapter, transactionStatusAdapter);
105
106 boolean rollback = false;
107
108 try {
109 return _methodInvocation.proceed();
110 }
111 catch (Throwable throwable) {
112 if (_transactionAttributeAdapter.rollbackOn(throwable)) {
113 TransactionLifecycleManager.fireTransactionRollbackedEvent(
114 _transactionAttributeAdapter, transactionStatusAdapter,
115 throwable);
116
117 if (transactionStatus.isNewTransaction()) {
118 rollback = true;
119 }
120
121 if (throwable instanceof RuntimeException) {
122 throw (RuntimeException)throwable;
123 }
124 else {
125 throw new ThrowableHolderException(throwable);
126 }
127 }
128 else {
129 return new ThrowableHolder(throwable);
130 }
131 }
132 finally {
133 if (!rollback) {
134 TransactionLifecycleManager.fireTransactionCommittedEvent(
135 _transactionAttributeAdapter, transactionStatusAdapter);
136 }
137 }
138 }
139
140 private CallbackPreferringTransactionCallback(
141 TransactionAttributeAdapter transactionAttributeAdapter,
142 MethodInvocation methodInvocation) {
143
144 _transactionAttributeAdapter = transactionAttributeAdapter;
145 _methodInvocation = methodInvocation;
146 }
147
148 private final MethodInvocation _methodInvocation;
149 private final TransactionAttributeAdapter _transactionAttributeAdapter;
150
151 }
152
153 }