wu979 commented on issue #31164:
URL:
https://github.com/apache/shardingsphere/issues/31164#issuecomment-2099651397
The business supports global data centers, so routing enforcement based on
the user's country is implemented in AOP aspects. However, some issues have
been identified. For instance, Data Center A is configured with read-write
separation. Forced routing might direct traffic to a secondary node, but if the
current operation is a write operation, ShardingSphere may execute the write
operation on the secondary node despite the enforced routing. Therefore,
considering read-write separation, compatibility with read-write operations
should be ensured. Currently, compatibility with ReadwriteSplittingSQLRouter
has been implemented. The code is as follows:
public final class ShardingReadwriteSplittingSQLRouter implements
SQLRouter<ReadwriteSplittingRule> {
@Override
public RouteContext createRouteContext(QueryContext queryContext,
RuleMetaData ruleMetaData, ShardingSphereDatabase shardingSphereDatabase,
ReadwriteSplittingRule rule, ConfigurationProperties configurationProperties,
ConnectionContext connectionContext) {
RouteContext result = new RouteContext();
ReadwriteSplittingDataSourceRule singleDataSourceRule =
rule.getSingleDataSourceRule();
String dataSourceName = (new
ReadwriteSplittingDataSourceRouter(singleDataSourceRule,
connectionContext)).route(queryContext.getSqlStatementContext(),
queryContext.getHintValueContext());
result.getRouteUnits().add(new RouteUnit(new
RouteMapper(singleDataSourceRule.getName(), dataSourceName),
Collections.emptyList()));
return result;
}
@Override
public void decorateRouteContext(RouteContext routeContext, QueryContext
queryContext, ShardingSphereDatabase database, ReadwriteSplittingRule rule,
ConfigurationProperties props, ConnectionContext connectionContext) {
Collection<RouteUnit> toBeRemoved = new LinkedList<>();
Collection<RouteUnit> toBeAdded = new LinkedList<>();
for (RouteUnit each : routeContext.getRouteUnits()) {
String dataSourceName =
each.getDataSourceMapper().getLogicName();
Optional<ReadwriteSplittingDataSourceRule> dataSourceRule =
rule.findDataSourceRule(dataSourceName);
if (dataSourceRule.isEmpty()) {
Map<String, ReadwriteSplittingDataSourceRule>
dataSourceMappers = rule.getDataSourceRules();
for (Map.Entry<String, ReadwriteSplittingDataSourceRule>
dataSourceMapper : dataSourceMappers.entrySet()) {
if
(dataSourceMapper.getValue().getDisabledDataSourceNames().contains(dataSourceName))
{
dataSourceRule =
rule.findDataSourceRule(dataSourceMapper.getKey());
if (dataSourceRule.isPresent()) {
toBeRemoved.add(each);
String actualDataSourceName = (new
ReadwriteSplittingDataSourceRouter(dataSourceRule.get(),
connectionContext)).route(queryContext.getSqlStatementContext(),
queryContext.getHintValueContext());
toBeAdded.add(new RouteUnit(new
RouteMapper(each.getDataSourceMapper().getLogicName(), actualDataSourceName),
each.getTableMappers()));
}
}
}
} else {
if
(dataSourceRule.get().getName().equalsIgnoreCase(each.getDataSourceMapper().getActualName()))
{
toBeRemoved.add(each);
String actualDataSourceName = (new
ReadwriteSplittingDataSourceRouter(dataSourceRule.get(),
connectionContext)).route(queryContext.getSqlStatementContext(),
queryContext.getHintValueContext());
toBeAdded.add(new RouteUnit(new
RouteMapper(each.getDataSourceMapper().getLogicName(), actualDataSourceName),
each.getTableMappers()));
}
}
}
routeContext.getRouteUnits().removeAll(toBeRemoved);
routeContext.getRouteUnits().addAll(toBeAdded);
}
@Override
public int getOrder() {
return ReadwriteSplittingOrder.ORDER + 2;
}
@Override
public Class<ReadwriteSplittingRule> getTypeClass() {
return ReadwriteSplittingRule.class;
}
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]