Skip to content
Snippets Groups Projects
Unverified Commit da31cf1e authored by spilledyear's avatar spilledyear Committed by GitHub
Browse files

bugfix: DataSourceProxyHolder#putDataSource deadlock (#3568)

parent efefd177
No related branches found
No related tags found
No related merge requests found
......@@ -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);
}
}
......@@ -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};
}
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment