001
014
015 package com.liferay.portal.spring.transaction;
016
017 import com.liferay.portal.kernel.annotation.AnnotationLocator;
018 import com.liferay.portal.kernel.transaction.Transactional;
019
020 import java.lang.reflect.Method;
021
022 import java.util.Map;
023 import java.util.concurrent.ConcurrentHashMap;
024 import java.util.concurrent.ConcurrentMap;
025
026 import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
027 import org.springframework.transaction.interceptor.TransactionAttribute;
028 import org.springframework.transaction.interceptor.TransactionAttributeSource;
029
030
033 public class AnnotationTransactionAttributeSource
034 implements TransactionAttributeSource {
035
036 @Override
037 public TransactionAttribute getTransactionAttribute(
038 Method method, Class<?> targetClass) {
039
040 Map<Method, TransactionAttribute> transactionAttributes =
041 _transactionAttributes.get(targetClass);
042
043 if (transactionAttributes == null) {
044 transactionAttributes = new ConcurrentHashMap<>();
045
046 Map<Method, TransactionAttribute> previousTransactionAttributes =
047 _transactionAttributes.putIfAbsent(
048 targetClass, transactionAttributes);
049
050 if (previousTransactionAttributes != null) {
051 transactionAttributes = previousTransactionAttributes;
052 }
053 }
054
055 TransactionAttribute transactionAttribute = transactionAttributes.get(
056 method);
057
058 if (transactionAttribute != null) {
059 if (transactionAttribute == _nullTransactionAttribute) {
060 return null;
061 }
062 else {
063 return transactionAttribute;
064 }
065 }
066
067 Transactional transactional = AnnotationLocator.locate(
068 method, targetClass, Transactional.class);
069
070 transactionAttribute = TransactionAttributeBuilder.build(transactional);
071
072 if (transactionAttribute == null) {
073 transactionAttributes.put(method, _nullTransactionAttribute);
074 }
075 else {
076 transactionAttributes.put(method, transactionAttribute);
077 }
078
079 return transactionAttribute;
080 }
081
082 private static final TransactionAttribute _nullTransactionAttribute =
083 new DefaultTransactionAttribute();
084
085 private final ConcurrentMap<Class<?>, Map<Method, TransactionAttribute>>
086 _transactionAttributes = new ConcurrentHashMap<>();
087
088 }