diff --git a/spring/src/main/java/io/seata/spring/annotation/datasource/DataSourceProxyHolder.java b/spring/src/main/java/io/seata/spring/annotation/datasource/DataSourceProxyHolder.java index e6993eca44f40871ce66f57aa68b7414a94b9d13..ff89b2dd1ecec31cac666c52f2a3dfda9c78a9c8 100644 --- a/spring/src/main/java/io/seata/spring/annotation/datasource/DataSourceProxyHolder.java +++ b/spring/src/main/java/io/seata/spring/annotation/datasource/DataSourceProxyHolder.java @@ -16,9 +16,9 @@ package io.seata.spring.annotation.datasource; import javax.sql.DataSource; -import java.util.concurrent.ConcurrentHashMap; +import java.util.HashMap; +import java.util.Map; -import io.seata.common.util.CollectionUtils; import io.seata.core.model.BranchType; import io.seata.rm.datasource.DataSourceProxy; import io.seata.rm.datasource.SeataDataSourceProxy; @@ -31,10 +31,10 @@ import io.seata.rm.datasource.xa.DataSourceProxyXA; */ public class DataSourceProxyHolder { private static final int MAP_INITIAL_CAPACITY = 8; - private ConcurrentHashMap<DataSource, SeataDataSourceProxy> dataSourceProxyMap; + private Map<DataSource, SeataDataSourceProxy> dataSourceProxyMap; private DataSourceProxyHolder() { - dataSourceProxyMap = new ConcurrentHashMap<>(MAP_INITIAL_CAPACITY); + dataSourceProxyMap = new HashMap<>(MAP_INITIAL_CAPACITY); } /** @@ -71,7 +71,7 @@ public class DataSourceProxyHolder { //If it's an right proxy, return it directly. if (dataSourceProxyMode == dataSourceProxy.getBranchType()) { - return (SeataDataSourceProxy)dataSource; + return (SeataDataSourceProxy) dataSource; } //Get the original data source. @@ -79,7 +79,21 @@ public class DataSourceProxyHolder { } else { originalDataSource = dataSource; } - return CollectionUtils.computeIfAbsent(this.dataSourceProxyMap, originalDataSource, - BranchType.XA == dataSourceProxyMode ? DataSourceProxyXA::new : DataSourceProxy::new); + + SeataDataSourceProxy dsProxy = dataSourceProxyMap.get(originalDataSource); + if (dsProxy == null) { + synchronized (dataSourceProxyMap) { + dsProxy = dataSourceProxyMap.get(originalDataSource); + if (dsProxy == null) { + dsProxy = createDsProxyByMode(dataSourceProxyMode, originalDataSource); + dataSourceProxyMap.put(originalDataSource, dsProxy); + } + } + } + return dsProxy; + } + + private SeataDataSourceProxy createDsProxyByMode(BranchType mode, DataSource originDs) { + return BranchType.XA == mode ? new DataSourceProxyXA(originDs) : new DataSourceProxy(originDs); } } diff --git a/spring/src/main/java/io/seata/spring/annotation/datasource/SeataAutoDataSourceProxyAdvice.java b/spring/src/main/java/io/seata/spring/annotation/datasource/SeataAutoDataSourceProxyAdvice.java index 0e497874e07a08ae4ff950c05578646089706c88..bfddd97ff0250c74d0430e90fce5785b74c8f573 100644 --- a/spring/src/main/java/io/seata/spring/annotation/datasource/SeataAutoDataSourceProxyAdvice.java +++ b/spring/src/main/java/io/seata/spring/annotation/datasource/SeataAutoDataSourceProxyAdvice.java @@ -15,8 +15,8 @@ */ package io.seata.spring.annotation.datasource; -import java.lang.reflect.Method; import javax.sql.DataSource; +import java.lang.reflect.Method; import io.seata.core.context.RootContext; import io.seata.core.model.BranchType; @@ -53,15 +53,14 @@ public class SeataAutoDataSourceProxyAdvice implements MethodInterceptor, Introd @Override public Object invoke(MethodInvocation invocation) throws Throwable { - if (!RootContext.requireGlobalLock() - && dataSourceProxyMode != RootContext.getBranchType()) { + if (!RootContext.requireGlobalLock() && dataSourceProxyMode != RootContext.getBranchType()) { return invocation.proceed(); } Method method = invocation.getMethod(); Object[] args = invocation.getArguments(); Method m = BeanUtils.findDeclaredMethod(dataSourceProxyClazz, method.getName(), method.getParameterTypes()); - if (m != null) { + if (m != null && DataSource.class.isAssignableFrom(method.getDeclaringClass())) { SeataDataSourceProxy dataSourceProxy = DataSourceProxyHolder.get().putDataSource((DataSource) invocation.getThis(), dataSourceProxyMode); return m.invoke(dataSourceProxy, args); } else { @@ -73,4 +72,6 @@ public class SeataAutoDataSourceProxyAdvice implements MethodInterceptor, Introd public Class<?>[] getInterfaces() { return new Class[]{SeataProxy.class}; } + + }