This is an automated email from the ASF dual-hosted git repository.
zhangliang 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 f8a77fc add savepoint support for sharding-jdbc (#16434)
f8a77fc is described below
commit f8a77fcd0b7ea4203f045ec617f10c6a81293fe9
Author: JingShang Lu <[email protected]>
AuthorDate: Wed Mar 30 20:53:28 2022 +0800
add savepoint support for sharding-jdbc (#16434)
* add savepoint support for sharding-jdbc
---
.../driver/jdbc/core/ShardingSphereSavepoint.java | 67 ++++++++++++++++++++++
.../jdbc/core/connection/ConnectionManager.java | 67 ++++++++++++++++++++++
.../core/connection/ShardingSphereConnection.java | 31 ++++++++++
.../AbstractUnsupportedOperationConnection.java | 21 -------
.../connection/CircuitBreakerConnection.java | 23 ++++++++
.../UnsupportedOperationConnectionTest.java | 20 -------
6 files changed, 188 insertions(+), 41 deletions(-)
diff --git
a/shardingsphere-jdbc/shardingsphere-jdbc-core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/ShardingSphereSavepoint.java
b/shardingsphere-jdbc/shardingsphere-jdbc-core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/ShardingSphereSavepoint.java
new file mode 100644
index 0000000..ce88854
--- /dev/null
+++
b/shardingsphere-jdbc/shardingsphere-jdbc-core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/ShardingSphereSavepoint.java
@@ -0,0 +1,67 @@
+/*
+ * 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.driver.jdbc.core;
+
+import java.rmi.server.UID;
+import java.sql.SQLException;
+import java.sql.Savepoint;
+
+/**
+ * ShardingSphere savepoint.
+ */
+public final class ShardingSphereSavepoint implements Savepoint {
+
+ private final String savepointName;
+
+ public ShardingSphereSavepoint() {
+ savepointName = getUniqueId();
+ }
+
+ public ShardingSphereSavepoint(final String name) throws SQLException {
+ if (null == name || 0 == name.length()) {
+ throw new SQLException("Savepoint name can not be NULL or empty");
+ }
+ savepointName = name;
+ }
+
+ @Override
+ public int getSavepointId() throws SQLException {
+ throw new SQLException("Only named savepoint are supported.");
+ }
+
+ @Override
+ public String getSavepointName() {
+ return savepointName;
+ }
+
+ private static String getUniqueId() {
+ String uidStr = new UID().toString();
+ int uidLength = uidStr.length();
+ StringBuilder safeString = new StringBuilder(uidLength + 1);
+ safeString.append('_');
+ for (int i = 0; i < uidLength; i++) {
+ char c = uidStr.charAt(i);
+ if (Character.isLetter(c) || Character.isDigit(c)) {
+ safeString.append(c);
+ } else {
+ safeString.append('_');
+ }
+ }
+ return safeString.toString();
+ }
+}
diff --git
a/shardingsphere-jdbc/shardingsphere-jdbc-core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/connection/ConnectionManager.java
b/shardingsphere-jdbc/shardingsphere-jdbc-core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/connection/ConnectionManager.java
index ac4701a..c9474ac 100644
---
a/shardingsphere-jdbc/shardingsphere-jdbc-core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/connection/ConnectionManager.java
+++
b/shardingsphere-jdbc/shardingsphere-jdbc-core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/connection/ConnectionManager.java
@@ -24,6 +24,7 @@ import com.google.common.collect.Sets;
import lombok.Getter;
import
org.apache.shardingsphere.driver.jdbc.adapter.executor.ForceExecuteTemplate;
import
org.apache.shardingsphere.driver.jdbc.adapter.invocation.MethodInvocationRecorder;
+import org.apache.shardingsphere.driver.jdbc.core.ShardingSphereSavepoint;
import
org.apache.shardingsphere.infra.datasource.pool.creator.DataSourcePoolCreator;
import org.apache.shardingsphere.infra.datasource.props.DataSourceProperties;
import
org.apache.shardingsphere.infra.executor.sql.execute.engine.ConnectionMode;
@@ -34,6 +35,7 @@ import
org.apache.shardingsphere.infra.metadata.user.ShardingSphereUser;
import org.apache.shardingsphere.mode.manager.ContextManager;
import org.apache.shardingsphere.mode.metadata.persist.MetaDataPersistService;
import org.apache.shardingsphere.traffic.rule.TrafficRule;
+import org.apache.shardingsphere.transaction.ConnectionSavepointManager;
import org.apache.shardingsphere.transaction.ConnectionTransaction;
import org.apache.shardingsphere.transaction.core.TransactionType;
import org.apache.shardingsphere.transaction.core.TransactionTypeHolder;
@@ -43,6 +45,7 @@ import javax.sql.DataSource;
import java.security.SecureRandom;
import java.sql.Connection;
import java.sql.SQLException;
+import java.sql.Savepoint;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -169,6 +172,70 @@ public final class ConnectionManager implements
ExecutorJDBCConnectionManager, A
}
/**
+ * Rollback to savepoint.
+ *
+ * @param savepoint savepoint
+ * @throws SQLException SQL exception
+ */
+ public void rollback(final Savepoint savepoint) throws SQLException {
+ for (Connection each : cachedConnections.values()) {
+ ConnectionSavepointManager.getInstance().rollbackToSavepoint(each,
savepoint.getSavepointName());
+ }
+ }
+
+ /**
+ * Set savepoint.
+ *
+ * @param savepointName savepoint name
+ * @return savepoint savepoint
+ * @throws SQLException SQL exception
+ */
+ public Savepoint setSavepoint(final String savepointName) throws
SQLException {
+ if (!connectionTransaction.isInTransaction()) {
+ throw new SQLException("Savepoint can only be used in transaction
blocks.");
+ }
+ ShardingSphereSavepoint result = new
ShardingSphereSavepoint(savepointName);
+ for (Connection each : cachedConnections.values()) {
+ ConnectionSavepointManager.getInstance().setSavepoint(each,
savepointName);
+ }
+ methodInvocationRecorder.record("setSavepoint", target ->
ConnectionSavepointManager.getInstance().setSavepoint(target, savepointName));
+ return result;
+ }
+
+ /**
+ * Set savepoint.
+ *
+ * @return savepoint savepoint
+ * @throws SQLException SQL exception
+ */
+ public Savepoint setSavepoint() throws SQLException {
+ if (!connectionTransaction.isInTransaction()) {
+ throw new SQLException("Savepoint can only be used in transaction
blocks.");
+ }
+ ShardingSphereSavepoint result = new ShardingSphereSavepoint();
+ for (Connection each : cachedConnections.values()) {
+ ConnectionSavepointManager.getInstance().setSavepoint(each,
result.getSavepointName());
+ }
+ methodInvocationRecorder.record("setSavepoint", target ->
ConnectionSavepointManager.getInstance().setSavepoint(target,
result.getSavepointName()));
+ return result;
+ }
+
+ /**
+ * Release savepoint.
+ *
+ * @param savepoint savepoint
+ * @throws SQLException SQL exception
+ */
+ public void releaseSavepoint(final Savepoint savepoint) throws
SQLException {
+ if (!connectionTransaction.isInTransaction()) {
+ return;
+ }
+ for (Connection each : cachedConnections.values()) {
+ ConnectionSavepointManager.getInstance().releaseSavepoint(each,
savepoint.getSavepointName());
+ }
+ }
+
+ /**
* Get transaction isolation.
*
* @return transaction isolation level
diff --git
a/shardingsphere-jdbc/shardingsphere-jdbc-core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/connection/ShardingSphereConnection.java
b/shardingsphere-jdbc/shardingsphere-jdbc-core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/connection/ShardingSphereConnection.java
index 838c1b4..b12f67c 100644
---
a/shardingsphere-jdbc/shardingsphere-jdbc-core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/connection/ShardingSphereConnection.java
+++
b/shardingsphere-jdbc/shardingsphere-jdbc-core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/connection/ShardingSphereConnection.java
@@ -30,6 +30,7 @@ import java.sql.Array;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.SQLException;
+import java.sql.Savepoint;
import java.sql.Statement;
/**
@@ -178,6 +179,36 @@ public final class ShardingSphereConnection extends
AbstractConnectionAdapter {
}
}
+ @Override
+ public void rollback(final Savepoint savepoint) throws SQLException {
+ checkClose();
+ connectionManager.rollback(savepoint);
+ }
+
+ @Override
+ public Savepoint setSavepoint(final String name) throws SQLException {
+ checkClose();
+ return connectionManager.setSavepoint(name);
+ }
+
+ @Override
+ public Savepoint setSavepoint() throws SQLException {
+ checkClose();
+ return connectionManager.setSavepoint();
+ }
+
+ @Override
+ public void releaseSavepoint(final Savepoint savepoint) throws
SQLException {
+ checkClose();
+ connectionManager.releaseSavepoint(savepoint);
+ }
+
+ private void checkClose() throws SQLException {
+ if (isClosed()) {
+ throw new SQLException("This connection has been closed");
+ }
+ }
+
@SuppressWarnings("MagicConstant")
@Override
public int getTransactionIsolation() throws SQLException {
diff --git
a/shardingsphere-jdbc/shardingsphere-jdbc-core/src/main/java/org/apache/shardingsphere/driver/jdbc/unsupported/AbstractUnsupportedOperationConnection.java
b/shardingsphere-jdbc/shardingsphere-jdbc-core/src/main/java/org/apache/shardingsphere/driver/jdbc/unsupported/AbstractUnsupportedOperationConnection.java
index 575370f..3fda4fc 100644
---
a/shardingsphere-jdbc/shardingsphere-jdbc-core/src/main/java/org/apache/shardingsphere/driver/jdbc/unsupported/AbstractUnsupportedOperationConnection.java
+++
b/shardingsphere-jdbc/shardingsphere-jdbc-core/src/main/java/org/apache/shardingsphere/driver/jdbc/unsupported/AbstractUnsupportedOperationConnection.java
@@ -27,7 +27,6 @@ import java.sql.NClob;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.sql.SQLXML;
-import java.sql.Savepoint;
import java.sql.Struct;
import java.util.Map;
import java.util.Properties;
@@ -59,26 +58,6 @@ public abstract class AbstractUnsupportedOperationConnection
extends WrapperAdap
}
@Override
- public final Savepoint setSavepoint() throws SQLException {
- throw new SQLFeatureNotSupportedException("setSavepoint");
- }
-
- @Override
- public final Savepoint setSavepoint(final String name) throws SQLException
{
- throw new SQLFeatureNotSupportedException("setSavepoint name");
- }
-
- @Override
- public final void releaseSavepoint(final Savepoint savepoint) throws
SQLException {
- throw new SQLFeatureNotSupportedException("releaseSavepoint");
- }
-
- @Override
- public final void rollback(final Savepoint savepoint) throws SQLException {
- throw new SQLFeatureNotSupportedException("rollback savepoint");
- }
-
- @Override
public final void abort(final Executor executor) throws SQLException {
throw new SQLFeatureNotSupportedException("abort");
}
diff --git
a/shardingsphere-jdbc/shardingsphere-jdbc-core/src/main/java/org/apache/shardingsphere/driver/state/circuit/connection/CircuitBreakerConnection.java
b/shardingsphere-jdbc/shardingsphere-jdbc-core/src/main/java/org/apache/shardingsphere/driver/state/circuit/connection/CircuitBreakerConnection.java
index a79dd81..dce8fae 100644
---
a/shardingsphere-jdbc/shardingsphere-jdbc-core/src/main/java/org/apache/shardingsphere/driver/state/circuit/connection/CircuitBreakerConnection.java
+++
b/shardingsphere-jdbc/shardingsphere-jdbc-core/src/main/java/org/apache/shardingsphere/driver/state/circuit/connection/CircuitBreakerConnection.java
@@ -26,7 +26,10 @@ import
org.apache.shardingsphere.driver.jdbc.unsupported.AbstractUnsupportedOper
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
import java.sql.SQLWarning;
+import java.sql.Savepoint;
import java.sql.Statement;
/**
@@ -93,6 +96,26 @@ public final class CircuitBreakerConnection extends
AbstractUnsupportedOperation
}
@Override
+ public void rollback(final Savepoint savepoint) throws SQLException {
+ throw new SQLFeatureNotSupportedException("rollback savepoint");
+ }
+
+ @Override
+ public Savepoint setSavepoint() throws SQLException {
+ throw new SQLFeatureNotSupportedException("setSavepoint");
+ }
+
+ @Override
+ public Savepoint setSavepoint(final String name) throws SQLException {
+ throw new SQLFeatureNotSupportedException("setSavepoint name");
+ }
+
+ @Override
+ public void releaseSavepoint(final Savepoint savepoint) throws
SQLException {
+ throw new SQLFeatureNotSupportedException("releaseSavepoint");
+ }
+
+ @Override
public void setHoldability(final int holdability) {
}
diff --git
a/shardingsphere-jdbc/shardingsphere-jdbc-core/src/test/java/org/apache/shardingsphere/driver/jdbc/unsupported/UnsupportedOperationConnectionTest.java
b/shardingsphere-jdbc/shardingsphere-jdbc-core/src/test/java/org/apache/shardingsphere/driver/jdbc/unsupported/UnsupportedOperationConnectionTest.java
index 96fad7d..ba17978 100644
---
a/shardingsphere-jdbc/shardingsphere-jdbc-core/src/test/java/org/apache/shardingsphere/driver/jdbc/unsupported/UnsupportedOperationConnectionTest.java
+++
b/shardingsphere-jdbc/shardingsphere-jdbc-core/src/test/java/org/apache/shardingsphere/driver/jdbc/unsupported/UnsupportedOperationConnectionTest.java
@@ -63,26 +63,6 @@ public final class UnsupportedOperationConnectionTest {
}
@Test(expected = SQLFeatureNotSupportedException.class)
- public void assertSetSavepoint() throws SQLException {
- shardingSphereConnection.setSavepoint();
- }
-
- @Test(expected = SQLFeatureNotSupportedException.class)
- public void assertSetSavepointWithName() throws SQLException {
- shardingSphereConnection.setSavepoint("");
- }
-
- @Test(expected = SQLFeatureNotSupportedException.class)
- public void assertReleaseSavepoint() throws SQLException {
- shardingSphereConnection.releaseSavepoint(null);
- }
-
- @Test(expected = SQLFeatureNotSupportedException.class)
- public void assertRollback() throws SQLException {
- shardingSphereConnection.rollback(null);
- }
-
- @Test(expected = SQLFeatureNotSupportedException.class)
public void assertAbort() throws SQLException {
shardingSphereConnection.abort(null);
}