This is an automated email from the ASF dual-hosted git repository.
terrymanu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git
The following commit(s) were added to refs/heads/master by this push:
new a78522c59c5 Handle unavailable read data sources in
readwrite-splitting (#39343)
a78522c59c5 is described below
commit a78522c59c59a9fea32da0439065d02ecc320442
Author: Liang Zhang <[email protected]>
AuthorDate: Wed Aug 5 12:08:04 2026 +0800
Handle unavailable read data sources in readwrite-splitting (#39343)
---
.../user-manual/error-code/sql-error-code.cn.md | 1 +
.../user-manual/error-code/sql-error-code.en.md | 1 +
...eReadwriteSplittingReadDataSourceException.java | 33 ++++++++++++++++++++++
...StandardReadwriteSplittingDataSourceRouter.java | 6 +++-
.../ReadwriteSplittingDataSourceRouterTest.java | 2 +-
...dardReadwriteSplittingDataSourceRouterTest.java | 14 +++++++++
6 files changed, 55 insertions(+), 2 deletions(-)
diff --git a/docs/document/content/user-manual/error-code/sql-error-code.cn.md
b/docs/document/content/user-manual/error-code/sql-error-code.cn.md
index bb0cf35bb08..62dce0de3ee 100644
--- a/docs/document/content/user-manual/error-code/sql-error-code.cn.md
+++ b/docs/document/content/user-manual/error-code/sql-error-code.cn.md
@@ -213,6 +213,7 @@ SQL 错误码以标准的 SQL State,Vendor Code 和详细错误信息提供,
| 20203 | 42S02 | Can not find readwrite-splitting [READ/WRITE] data
source '%s' in %s. |
| 20204 | 42S01 | Readwrite-splitting [READ/WRITE] data source '%s'
is duplicated in %s. |
| 20205 | 44000 | Readwrite-splitting [READ/WRITE] data source
inline expression error in %s. |
+| 20206 | 42S02 | No available read data source in
readwrite-splitting data source rule '%s'. |
### SQL 方言转换
diff --git a/docs/document/content/user-manual/error-code/sql-error-code.en.md
b/docs/document/content/user-manual/error-code/sql-error-code.en.md
index 7d35fa94657..13b63c224d7 100644
--- a/docs/document/content/user-manual/error-code/sql-error-code.en.md
+++ b/docs/document/content/user-manual/error-code/sql-error-code.en.md
@@ -213,6 +213,7 @@ SQL error codes provide by standard `SQL State`, `Vendor
Code` and `Reason`, whi
| 20203 | 42S02 | Can not find readwrite-splitting [READ/WRITE] data
source '%s' in %s. |
| 20204 | 42S01 | Readwrite-splitting [READ/WRITE] data source '%s'
is duplicated in %s. |
| 20205 | 44000 | Readwrite-splitting [READ/WRITE] data source
inline expression error in %s. |
+| 20206 | 42S02 | No available read data source in
readwrite-splitting data source rule '%s'. |
### SQL Dialect Translator
diff --git
a/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/exception/route/NoAvailableReadwriteSplittingReadDataSourceException.java
b/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/exception/route/NoAvailableReadwriteSplittingReadDataSourceException.java
new file mode 100644
index 00000000000..b9c7c7e317a
--- /dev/null
+++
b/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/exception/route/NoAvailableReadwriteSplittingReadDataSourceException.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.readwritesplitting.exception.route;
+
+import
org.apache.shardingsphere.infra.exception.external.sql.sqlstate.XOpenSQLState;
+import
org.apache.shardingsphere.readwritesplitting.exception.ReadwriteSplittingSQLException;
+
+/**
+ * No available readwrite-splitting read data source exception.
+ */
+public final class NoAvailableReadwriteSplittingReadDataSourceException
extends ReadwriteSplittingSQLException {
+
+ private static final long serialVersionUID = 5132658319931046280L;
+
+ public NoAvailableReadwriteSplittingReadDataSourceException(final String
dataSourceRuleName) {
+ super(XOpenSQLState.NOT_FOUND, 6, "No available read data source in
readwrite-splitting data source rule '%s'.", dataSourceRuleName);
+ }
+}
diff --git
a/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/standard/StandardReadwriteSplittingDataSourceRouter.java
b/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/standard/StandardReadwriteSplittingDataSourceRouter.java
index 0ea5ef0c038..6d9bcf5a860 100644
---
a/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/standard/StandardReadwriteSplittingDataSourceRouter.java
+++
b/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/route/standard/StandardReadwriteSplittingDataSourceRouter.java
@@ -17,6 +17,8 @@
package org.apache.shardingsphere.readwritesplitting.route.standard;
+import org.apache.shardingsphere.infra.exception.ShardingSpherePreconditions;
+import
org.apache.shardingsphere.readwritesplitting.exception.route.NoAvailableReadwriteSplittingReadDataSourceException;
import
org.apache.shardingsphere.readwritesplitting.route.standard.filter.ReadDataSourcesFilter;
import
org.apache.shardingsphere.readwritesplitting.route.standard.filter.type.DisabledReadDataSourcesFilter;
import
org.apache.shardingsphere.readwritesplitting.rule.ReadwriteSplittingDataSourceGroupRule;
@@ -39,7 +41,9 @@ public final class StandardReadwriteSplittingDataSourceRouter
{
* @return routed data source name
*/
public String route(final ReadwriteSplittingDataSourceGroupRule rule) {
- return rule.getLoadBalancer().getTargetName(rule.getName(),
getFilteredReadDataSources(rule));
+ List<String> availableReadDataSources =
getFilteredReadDataSources(rule);
+ ShardingSpherePreconditions.checkNotEmpty(availableReadDataSources, ()
-> new NoAvailableReadwriteSplittingReadDataSourceException(rule.getName()));
+ return rule.getLoadBalancer().getTargetName(rule.getName(),
availableReadDataSources);
}
private List<String> getFilteredReadDataSources(final
ReadwriteSplittingDataSourceGroupRule rule) {
diff --git
a/features/readwrite-splitting/core/src/test/java/org/apache/shardingsphere/readwritesplitting/route/ReadwriteSplittingDataSourceRouterTest.java
b/features/readwrite-splitting/core/src/test/java/org/apache/shardingsphere/readwritesplitting/route/ReadwriteSplittingDataSourceRouterTest.java
index 91f6ef07d8b..3da02c9e996 100644
---
a/features/readwrite-splitting/core/src/test/java/org/apache/shardingsphere/readwritesplitting/route/ReadwriteSplittingDataSourceRouterTest.java
+++
b/features/readwrite-splitting/core/src/test/java/org/apache/shardingsphere/readwritesplitting/route/ReadwriteSplittingDataSourceRouterTest.java
@@ -66,7 +66,7 @@ class ReadwriteSplittingDataSourceRouterTest {
@Test
void assertRouteWithStandardRouters() {
when(rule.getDisabledDataSourceNames()).thenReturn(Collections.emptyList());
-
when(rule.getReadwriteSplittingGroup().getReadDataSources()).thenReturn(Collections.emptyList());
+
when(rule.getReadwriteSplittingGroup().getReadDataSources()).thenReturn(Collections.singletonList("standard_ds"));
when(rule.getLoadBalancer().getTargetName(any(),
any())).thenReturn("standard_ds");
ReadwriteSplittingDataSourceRouter router = new
ReadwriteSplittingDataSourceRouter(rule, mock(ConnectionContext.class));
setQualifiedRouters(router,
mock(QualifiedReadwriteSplittingDataSourceRouter.class));
diff --git
a/features/readwrite-splitting/core/src/test/java/org/apache/shardingsphere/readwritesplitting/route/standard/StandardReadwriteSplittingDataSourceRouterTest.java
b/features/readwrite-splitting/core/src/test/java/org/apache/shardingsphere/readwritesplitting/route/standard/StandardReadwriteSplittingDataSourceRouterTest.java
index df844a7539d..e6a7d910a9e 100644
---
a/features/readwrite-splitting/core/src/test/java/org/apache/shardingsphere/readwritesplitting/route/standard/StandardReadwriteSplittingDataSourceRouterTest.java
+++
b/features/readwrite-splitting/core/src/test/java/org/apache/shardingsphere/readwritesplitting/route/standard/StandardReadwriteSplittingDataSourceRouterTest.java
@@ -19,15 +19,18 @@ package
org.apache.shardingsphere.readwritesplitting.route.standard;
import
org.apache.shardingsphere.infra.algorithm.loadbalancer.round.robin.RoundRobinLoadBalanceAlgorithm;
import
org.apache.shardingsphere.readwritesplitting.config.rule.ReadwriteSplittingDataSourceGroupRuleConfiguration;
+import
org.apache.shardingsphere.readwritesplitting.exception.route.NoAvailableReadwriteSplittingReadDataSourceException;
import
org.apache.shardingsphere.readwritesplitting.transaction.TransactionalReadQueryStrategy;
import
org.apache.shardingsphere.readwritesplitting.rule.ReadwriteSplittingDataSourceGroupRule;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import java.sql.SQLException;
import java.util.Arrays;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertThrows;
class StandardReadwriteSplittingDataSourceRouterTest {
@@ -50,4 +53,15 @@ class StandardReadwriteSplittingDataSourceRouterTest {
rule.disableDataSource("read_ds_0");
assertThat(new
StandardReadwriteSplittingDataSourceRouter().route(rule), is("read_ds_1"));
}
+
+ @Test
+ void assertRouteWithAllReadDataSourcesDisabled() {
+ rule.disableDataSource("read_ds_0");
+ rule.disableDataSource("read_ds_1");
+ SQLException actual =
assertThrows(NoAvailableReadwriteSplittingReadDataSourceException.class,
+ () -> new
StandardReadwriteSplittingDataSourceRouter().route(rule)).toSQLException();
+ assertThat(actual.getErrorCode(), is(20206));
+ assertThat(actual.getSQLState(), is("42S02"));
+ assertThat(actual.getMessage(), is("No available read data source in
readwrite-splitting data source rule 'test_config'."));
+ }
}