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 {

Reply via email to