This is an automated email from the ASF dual-hosted git repository.
duanzhengqiang 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 73408f9b37f Support release savepoint in MySQL (#25004)
73408f9b37f is described below
commit 73408f9b37f973709442b739fd0953d9dc357b50
Author: ZhangCheng <[email protected]>
AuthorDate: Tue Apr 4 15:52:55 2023 +0800
Support release savepoint in MySQL (#25004)
* Support release savepoint in MySQL
* Support release savepoint in MySQL
---
.../transaction/ConnectionSavepointManager.java | 11 ++++++++++-
.../transaction/ConnectionSavepointManagerTest.java | 18 ++++++++++++++++++
.../cases/savepoint/MySQLSavePointTestCase.java | 21 +++++++++++++++++++++
.../settype/TransactionTypeHolderTestCase.java | 7 ++++---
.../engine/base/TransactionBaseE2EIT.java | 2 +-
5 files changed, 54 insertions(+), 5 deletions(-)
diff --git
a/kernel/transaction/core/src/main/java/org/apache/shardingsphere/transaction/ConnectionSavepointManager.java
b/kernel/transaction/core/src/main/java/org/apache/shardingsphere/transaction/ConnectionSavepointManager.java
index 6e5b78953dd..422477c08c7 100644
---
a/kernel/transaction/core/src/main/java/org/apache/shardingsphere/transaction/ConnectionSavepointManager.java
+++
b/kernel/transaction/core/src/main/java/org/apache/shardingsphere/transaction/ConnectionSavepointManager.java
@@ -19,10 +19,13 @@ package org.apache.shardingsphere.transaction;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
+import org.apache.shardingsphere.infra.database.type.DatabaseTypeEngine;
+import org.apache.shardingsphere.infra.database.type.dialect.MySQLDatabaseType;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Savepoint;
+import java.sql.Statement;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;
@@ -83,7 +86,13 @@ public final class ConnectionSavepointManager {
public void releaseSavepoint(final Connection connection, final String
savepointName) throws SQLException {
Optional<Savepoint> result = lookupSavepoint(connection,
savepointName);
if (result.isPresent()) {
- connection.releaseSavepoint(result.get());
+ if
(DatabaseTypeEngine.getDatabaseType(connection.getMetaData().getURL())
instanceof MySQLDatabaseType) {
+ try (Statement statement = connection.createStatement()) {
+ statement.execute(String.format("RELEASE SAVEPOINT %s",
savepointName));
+ }
+ } else {
+ connection.releaseSavepoint(result.get());
+ }
}
}
diff --git
a/kernel/transaction/core/src/test/java/org/apache/shardingsphere/transaction/ConnectionSavepointManagerTest.java
b/kernel/transaction/core/src/test/java/org/apache/shardingsphere/transaction/ConnectionSavepointManagerTest.java
index 5bd276a2438..138138d19da 100644
---
a/kernel/transaction/core/src/test/java/org/apache/shardingsphere/transaction/ConnectionSavepointManagerTest.java
+++
b/kernel/transaction/core/src/test/java/org/apache/shardingsphere/transaction/ConnectionSavepointManagerTest.java
@@ -24,10 +24,13 @@ import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.sql.Connection;
+import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.sql.Savepoint;
+import java.sql.Statement;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -64,10 +67,25 @@ class ConnectionSavepointManagerTest {
@Test
void assertSaveReleaseSavingPoint() throws SQLException {
ConnectionSavepointManager.getInstance().setSavepoint(connection,
SAVE_POINT);
+ DatabaseMetaData databaseMetaData = mock(DatabaseMetaData.class);
+ when(connection.getMetaData()).thenReturn(databaseMetaData);
+
when(connection.getMetaData().getURL()).thenReturn("jdbc:postgresql://127.0.0.1:5432/foo_ds");
ConnectionSavepointManager.getInstance().releaseSavepoint(connection,
SAVE_POINT);
verify(connection).releaseSavepoint(savepoint);
}
+ @Test
+ void assertSaveReleaseSavingPointOfMySQL() throws SQLException {
+ ConnectionSavepointManager.getInstance().setSavepoint(connection,
SAVE_POINT);
+ DatabaseMetaData databaseMetaData = mock(DatabaseMetaData.class);
+ when(connection.getMetaData()).thenReturn(databaseMetaData);
+
when(connection.getMetaData().getURL()).thenReturn("jdbc:mysql://127.0.0.1:3306/foo_ds");
+ Statement statement = mock(Statement.class);
+ when(connection.createStatement()).thenReturn(statement);
+ ConnectionSavepointManager.getInstance().releaseSavepoint(connection,
SAVE_POINT);
+ verify(statement).execute(String.format("RELEASE SAVEPOINT %s",
SAVE_POINT));
+ }
+
@Test
void assertTransactionFinished() throws SQLException {
ConnectionSavepointManager.getInstance().setSavepoint(connection,
SAVE_POINT);
diff --git
a/test/e2e/operation/transaction/src/test/java/org/apache/shardingsphere/test/e2e/transaction/cases/savepoint/MySQLSavePointTestCase.java
b/test/e2e/operation/transaction/src/test/java/org/apache/shardingsphere/test/e2e/transaction/cases/savepoint/MySQLSavePointTestCase.java
index e0ab9724fac..5ad98bcdd51 100644
---
a/test/e2e/operation/transaction/src/test/java/org/apache/shardingsphere/test/e2e/transaction/cases/savepoint/MySQLSavePointTestCase.java
+++
b/test/e2e/operation/transaction/src/test/java/org/apache/shardingsphere/test/e2e/transaction/cases/savepoint/MySQLSavePointTestCase.java
@@ -23,8 +23,12 @@ import
org.apache.shardingsphere.test.e2e.transaction.engine.base.TransactionTes
import
org.apache.shardingsphere.test.e2e.transaction.engine.constants.TransactionTestConstants;
import javax.sql.DataSource;
+import java.sql.Connection;
import java.sql.SQLException;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
/**
* MySQL savepoint transaction integration test.
*/
@@ -39,5 +43,22 @@ public final class MySQLSavePointTestCase extends
BaseSavePointTestCase {
public void executeTest(final TransactionContainerComposer
containerComposer) throws SQLException {
assertRollback2Savepoint();
assertReleaseSavepoint();
+ assertReleaseSavepointFailure();
+ }
+
+ private void assertReleaseSavepointFailure() throws SQLException {
+ try (Connection connection = getDataSource().getConnection()) {
+ executeWithLog(connection, "DELETE FROM account");
+ connection.setAutoCommit(false);
+ executeWithLog(connection, "INSERT INTO account(id, balance,
transaction_id) VALUES(1,1,1)");
+ executeWithLog(connection, "SAVEPOINT point1");
+ executeWithLog(connection, "RELEASE SAVEPOINT point1");
+ try {
+ executeWithLog(connection, "ROLLBACK TO SAVEPOINT point1");
+ } catch (final SQLException ex) {
+ assertThat(ex.getMessage(), is("SAVEPOINT point1 does not
exist"));
+ }
+ connection.rollback();
+ }
}
}
diff --git
a/test/e2e/operation/transaction/src/test/java/org/apache/shardingsphere/test/e2e/transaction/cases/settype/TransactionTypeHolderTestCase.java
b/test/e2e/operation/transaction/src/test/java/org/apache/shardingsphere/test/e2e/transaction/cases/settype/TransactionTypeHolderTestCase.java
index 7e430cf910e..a9ffc4f9595 100644
---
a/test/e2e/operation/transaction/src/test/java/org/apache/shardingsphere/test/e2e/transaction/cases/settype/TransactionTypeHolderTestCase.java
+++
b/test/e2e/operation/transaction/src/test/java/org/apache/shardingsphere/test/e2e/transaction/cases/settype/TransactionTypeHolderTestCase.java
@@ -31,6 +31,7 @@ import java.sql.SQLException;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertNull;
/**
* Transaction type holder test case.
@@ -44,14 +45,14 @@ public final class TransactionTypeHolderTestCase extends
BaseTransactionTestCase
@Override
protected void executeTest(final TransactionContainerComposer
containerComposer) throws SQLException {
+ TransactionTypeHolder.set(TransactionType.LOCAL);
try (Connection connection = getDataSource().getConnection()) {
- TransactionTypeHolder.set(TransactionType.LOCAL);
assertThat(TransactionTypeHolder.get(), is(TransactionType.LOCAL));
connection.setAutoCommit(false);
connection.rollback();
} finally {
- TransactionTypeHolder.set(TransactionType.XA);
- assertThat(TransactionTypeHolder.get(), is(TransactionType.XA));
+ TransactionTypeHolder.clear();
+ assertNull(TransactionTypeHolder.get());
}
}
}
diff --git
a/test/e2e/operation/transaction/src/test/java/org/apache/shardingsphere/test/e2e/transaction/engine/base/TransactionBaseE2EIT.java
b/test/e2e/operation/transaction/src/test/java/org/apache/shardingsphere/test/e2e/transaction/engine/base/TransactionBaseE2EIT.java
index facdc0299f8..040ba7e0826 100644
---
a/test/e2e/operation/transaction/src/test/java/org/apache/shardingsphere/test/e2e/transaction/engine/base/TransactionBaseE2EIT.java
+++
b/test/e2e/operation/transaction/src/test/java/org/apache/shardingsphere/test/e2e/transaction/engine/base/TransactionBaseE2EIT.java
@@ -155,7 +155,7 @@ public abstract class TransactionBaseE2EIT {
private void doCallTestCases(final TransactionTestParameter testParam,
final TransactionType transactionType, final String provider, final
TransactionContainerComposer containerComposer) {
for (Class<? extends BaseTransactionTestCase> each :
testParam.getTransactionTestCaseClasses()) {
if
(!Arrays.asList(each.getAnnotation(TransactionTestCase.class).transactionTypes()).contains(transactionType))
{
- return;
+ continue;
}
log.info("Call transaction IT {} -> {} -> {} -> {} test begin.",
testParam, transactionType, provider, each.getSimpleName());
try {