From 23a005afec47042655063d66440adcfa365e451b Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Fri, 16 Nov 2018 11:27:07 +0800 Subject: [PATCH 001/113] for checkstyle. --- .../backend/BackendHandlerFactory.java | 7 ++++--- .../backend/SchemaBroadcastBackendHandler.java | 14 +++++--------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/BackendHandlerFactory.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/BackendHandlerFactory.java index 46dbebf42277e..7d165747e1d96 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/BackendHandlerFactory.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/BackendHandlerFactory.java @@ -96,8 +96,9 @@ public static BackendHandler newBinaryProtocolInstance(final int connectionId, f final BackendConnection backendConnection, final DatabaseType databaseType, final String schema) { LogicSchema logicSchema = GLOBAL_REGISTRY.getLogicSchema(schema); backendConnection.setLogicSchema(logicSchema); - return GLOBAL_REGISTRY.getShardingProperties().getValue(ShardingPropertiesConstant.PROXY_BACKEND_USE_NIO) ? new NettyBackendHandler(logicSchema, connectionId, sequenceId, sql, databaseType) - : new JDBCBackendHandler(logicSchema, sql, new JDBCExecuteEngine(backendConnection, new PreparedStatementExecutorWrapper(logicSchema, parameters))); + return GLOBAL_REGISTRY.getShardingProperties().getValue(ShardingPropertiesConstant.PROXY_BACKEND_USE_NIO) + ? new NettyBackendHandler(logicSchema, connectionId, sequenceId, sql, databaseType) + : new JDBCBackendHandler(logicSchema, sql, new JDBCExecuteEngine(backendConnection, new PreparedStatementExecutorWrapper(logicSchema, parameters))); } /** @@ -115,7 +116,7 @@ public static BackendHandler createBackendHandler( final int connectionId, final int sequenceId, final String sql, final BackendConnection backendConnection, final DatabaseType databaseType, final FrontendHandler frontendHandler) { SQLStatement sqlStatement = new SQLJudgeEngine(sql).judge(); if (SQLType.DCL == sqlStatement.getType() || sqlStatement instanceof SetStatement) { - return new SchemaBroadcastBackendHandler(connectionId, sequenceId, sql, databaseType); + return new SchemaBroadcastBackendHandler(connectionId, sequenceId, sql, backendConnection, databaseType); } if (sqlStatement instanceof UseStatement || sqlStatement instanceof ShowDatabasesStatement) { diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/SchemaBroadcastBackendHandler.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/SchemaBroadcastBackendHandler.java index 465ee69aeb75e..483ec47d4bb5b 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/SchemaBroadcastBackendHandler.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/SchemaBroadcastBackendHandler.java @@ -22,11 +22,9 @@ import io.shardingsphere.shardingproxy.runtime.GlobalRegistry; import io.shardingsphere.shardingproxy.transport.common.packet.DatabasePacket; import io.shardingsphere.shardingproxy.transport.mysql.packet.command.CommandResponsePackets; -import io.shardingsphere.shardingproxy.transport.mysql.packet.generic.ErrPacket; import io.shardingsphere.shardingproxy.transport.mysql.packet.generic.OKPacket; import lombok.RequiredArgsConstructor; -import java.sql.SQLException; import java.util.Collection; import java.util.LinkedList; import java.util.List; @@ -45,19 +43,17 @@ public final class SchemaBroadcastBackendHandler implements BackendHandler { private final String sql; + private final BackendConnection backendConnection; + private final DatabaseType databaseType; @Override public CommandResponsePackets execute() { List packets = new LinkedList<>(); for (String schema : GlobalRegistry.getInstance().getSchemaNames()) { - try (BackendConnection backendConnection = new BackendConnection()) { - BackendHandler backendHandler = BackendHandlerFactory.newTextProtocolInstance(connectionId, sequenceId, sql, backendConnection, databaseType, schema); - CommandResponsePackets commandResponsePackets = backendHandler.execute(); - packets.addAll(commandResponsePackets.getPackets()); - } catch (final SQLException ex) { - return new CommandResponsePackets(new ErrPacket(1, ex)); - } + BackendHandler backendHandler = BackendHandlerFactory.newTextProtocolInstance(connectionId, sequenceId, sql, backendConnection, databaseType, schema); + CommandResponsePackets commandResponsePackets = backendHandler.execute(); + packets.addAll(commandResponsePackets.getPackets()); } return merge(packets); } From 5c1168dd1ed9aaa4e0031da80f3aab6571f45db1 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Fri, 16 Nov 2018 22:44:15 +0800 Subject: [PATCH 002/113] #1238 Change cachedConnections to HashMultimap --- .../backend/jdbc/connection/BackendConnection.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index 9dba82b56fe5c..7daf0d2ec9c8d 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -17,6 +17,8 @@ package io.shardingsphere.shardingproxy.backend.jdbc.connection; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; import io.shardingsphere.core.constant.ConnectionMode; import io.shardingsphere.core.routing.router.masterslave.MasterVisitedManager; import io.shardingsphere.shardingproxy.runtime.schema.LogicSchema; @@ -46,7 +48,7 @@ public final class BackendConnection implements AutoCloseable { @Setter private LogicSchema logicSchema; - private final Collection cachedConnections = new CopyOnWriteArrayList<>(); + private final Multimap cachedConnections = HashMultimap.create(); private final Collection cachedStatements = new CopyOnWriteArrayList<>(); @@ -58,7 +60,7 @@ public final class BackendConnection implements AutoCloseable { * @return connection size */ public int getConnectionSize() { - return cachedConnections.size(); + return cachedConnections.values().size(); } /** @@ -72,7 +74,7 @@ public int getConnectionSize() { */ public List getConnections(final ConnectionMode connectionMode, final String dataSourceName, final int connectionSize) throws SQLException { List result = logicSchema.getBackendDataSource().getConnections(connectionMode, dataSourceName, connectionSize); - cachedConnections.addAll(result); + cachedConnections.putAll(dataSourceName, result); return result; } @@ -142,7 +144,7 @@ private Collection closeStatements() { private Collection closeConnections() { Collection result = new LinkedList<>(); - for (Connection each : cachedConnections) { + for (Connection each : cachedConnections.values()) { try { each.close(); } catch (SQLException ex) { From 4d2ad3933e93cd1b333aa446b8363298efb4066b Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Fri, 16 Nov 2018 22:48:10 +0800 Subject: [PATCH 003/113] #1238 Add init BackendConnectionTest. --- .../connection/BackendConnectionTest.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java new file mode 100644 index 0000000000000..0b7ecb8175743 --- /dev/null +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java @@ -0,0 +1,21 @@ +/* + * Copyright 2016-2018 shardingsphere.io. + *

+ * Licensed 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 io.shardingsphere.shardingproxy.backend.jdbc.connection; + +public class BackendConnectionTest { +} From 52bef8fd80417f3891592932cbb884ed8bb45d60 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Fri, 16 Nov 2018 23:09:55 +0800 Subject: [PATCH 004/113] #1238 Add cached layer while getConnections. --- .../jdbc/connection/BackendConnection.java | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index 7daf0d2ec9c8d..cfd25adbc001e 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -30,6 +30,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; +import java.util.ArrayList; import java.util.Collection; import java.util.LinkedList; import java.util.List; @@ -73,8 +74,27 @@ public int getConnectionSize() { * @throws SQLException SQL exception */ public List getConnections(final ConnectionMode connectionMode, final String dataSourceName, final int connectionSize) throws SQLException { - List result = logicSchema.getBackendDataSource().getConnections(connectionMode, dataSourceName, connectionSize); - cachedConnections.putAll(dataSourceName, result); + Collection connections; + synchronized (cachedConnections) { + connections = cachedConnections.get(dataSourceName); + } + List result; + if (connections.size() >= connectionSize) { + result = new ArrayList<>(connections).subList(0, connectionSize); + } else if (!connections.isEmpty()) { + result = new ArrayList<>(connectionSize); + result.addAll(connections); + List newConnections = logicSchema.getBackendDataSource().getConnections(connectionMode, dataSourceName, connectionSize - connections.size()); + result.addAll(newConnections); + synchronized (cachedConnections) { + cachedConnections.putAll(dataSourceName, newConnections); + } + } else { + result = new ArrayList<>(logicSchema.getBackendDataSource().getConnections(connectionMode, dataSourceName, connectionSize)); + synchronized (cachedConnections) { + cachedConnections.putAll(dataSourceName, result); + } + } return result; } From e8f9d0cfef6ad42f1a050c30bae7f9795f7d97a7 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Sat, 17 Nov 2018 10:02:56 +0800 Subject: [PATCH 005/113] #1238 Add init case for BackendConnectionTest --- .../connection/BackendConnectionTest.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java index 0b7ecb8175743..9fc4cda6efb4d 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java @@ -17,5 +17,32 @@ package io.shardingsphere.shardingproxy.backend.jdbc.connection; +import org.junit.Test; + public class BackendConnectionTest { + + @Test + public void assertGetConnectionCacheIsEmpty() { + + } + + @Test + public void assertGetConnectionSizeLessThanCache() { + + } + + @Test + public void assertGetConnectionSizeGreaterThanCache() { + + } + + @Test + public void assertGetConnectionSizeIsOne() { + + } + + @Test + public void assertMultiThreadGetConnection() { + + } } From 4ec4d0d466476c096860e73aa5ea65542d001d3a Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Sat, 17 Nov 2018 10:15:37 +0800 Subject: [PATCH 006/113] #1238 Add Mock object for BackendConnectionTest. --- .../connection/BackendConnectionTest.java | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java index 9fc4cda6efb4d..6683e04bb8719 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java @@ -17,10 +17,43 @@ package io.shardingsphere.shardingproxy.backend.jdbc.connection; +import io.shardingsphere.core.constant.ConnectionMode; +import io.shardingsphere.shardingproxy.backend.jdbc.datasource.JDBCBackendDataSource; +import io.shardingsphere.shardingproxy.runtime.schema.LogicSchema; +import lombok.SneakyThrows; +import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import java.sql.Connection; +import java.util.List; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) public class BackendConnectionTest { + @Mock + private LogicSchema logicSchema; + + private BackendConnection backendConnection = new BackendConnection(); + + @Before + @SuppressWarnings("unchecked") + @SneakyThrows + public void setup() { + List newConnection = mock(List.class); + JDBCBackendDataSource backendDataSource = mock(JDBCBackendDataSource.class); + when(backendDataSource.getConnections((ConnectionMode) any(), anyString(), anyInt())).thenReturn(newConnection); + when(logicSchema.getBackendDataSource()).thenReturn(backendDataSource); + } + @Test public void assertGetConnectionCacheIsEmpty() { From fded98a148ace09d8f14bb834194d34d5dc93675 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Sat, 17 Nov 2018 10:40:04 +0800 Subject: [PATCH 007/113] #1238 Fill BackendConnectionTest.assertGetConnectionCacheIsEmpty. --- .../connection/BackendConnectionTest.java | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java index 6683e04bb8719..ad23e21d2af5c 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java @@ -28,11 +28,14 @@ import org.mockito.junit.MockitoJUnitRunner; import java.sql.Connection; +import java.util.ArrayList; import java.util.List; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -42,21 +45,26 @@ public class BackendConnectionTest { @Mock private LogicSchema logicSchema; + @Mock + private JDBCBackendDataSource backendDataSource; + private BackendConnection backendConnection = new BackendConnection(); @Before @SuppressWarnings("unchecked") @SneakyThrows public void setup() { - List newConnection = mock(List.class); - JDBCBackendDataSource backendDataSource = mock(JDBCBackendDataSource.class); - when(backendDataSource.getConnections((ConnectionMode) any(), anyString(), anyInt())).thenReturn(newConnection); when(logicSchema.getBackendDataSource()).thenReturn(backendDataSource); + backendConnection.setLogicSchema(logicSchema); } @Test + @SneakyThrows public void assertGetConnectionCacheIsEmpty() { - + when(backendDataSource.getConnections((ConnectionMode) any(), anyString(), eq(2))).thenReturn(mockNewConnections(2)); + List actualConnections = backendConnection.getConnections(ConnectionMode.MEMORY_STRICTLY, "ds1", 2); + assertThat(actualConnections.size(), is(2)); + assertThat(backendConnection.getConnectionSize(), is(2)); } @Test @@ -78,4 +86,13 @@ public void assertGetConnectionSizeIsOne() { public void assertMultiThreadGetConnection() { } + + private List mockNewConnections(final int connectionSize) { + List result = new ArrayList<>(); + for (int i = 0; i < connectionSize; i++) { + Connection connection = mock(Connection.class); + result.add(connection); + } + return result; + } } From 9a12622aa14b89d982b562407388fa57a9fc39de Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Sat, 17 Nov 2018 10:48:13 +0800 Subject: [PATCH 008/113] #1238 Fill BackendConnectionTest.assertGetConnectionSizeLessThanCache. --- .../connection/BackendConnectionTest.java | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java index ad23e21d2af5c..5d924d2d0a371 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java @@ -17,6 +17,8 @@ package io.shardingsphere.shardingproxy.backend.jdbc.connection; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; import io.shardingsphere.core.constant.ConnectionMode; import io.shardingsphere.shardingproxy.backend.jdbc.datasource.JDBCBackendDataSource; import io.shardingsphere.shardingproxy.runtime.schema.LogicSchema; @@ -27,7 +29,9 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; +import java.lang.reflect.Field; import java.sql.Connection; +import java.sql.SQLException; import java.util.ArrayList; import java.util.List; @@ -59,8 +63,7 @@ public void setup() { } @Test - @SneakyThrows - public void assertGetConnectionCacheIsEmpty() { + public void assertGetConnectionCacheIsEmpty() throws SQLException { when(backendDataSource.getConnections((ConnectionMode) any(), anyString(), eq(2))).thenReturn(mockNewConnections(2)); List actualConnections = backendConnection.getConnections(ConnectionMode.MEMORY_STRICTLY, "ds1", 2); assertThat(actualConnections.size(), is(2)); @@ -68,8 +71,11 @@ public void assertGetConnectionCacheIsEmpty() { } @Test - public void assertGetConnectionSizeLessThanCache() { - + public void assertGetConnectionSizeLessThanCache() throws SQLException { + setCachedConnections("ds1", 10); + List actualConnections = backendConnection.getConnections(ConnectionMode.MEMORY_STRICTLY, "ds1", 2); + assertThat(actualConnections.size(), is(2)); + assertThat(backendConnection.getConnectionSize(), is(10)); } @Test @@ -95,4 +101,13 @@ private List mockNewConnections(final int connectionSize) { } return result; } + + @SneakyThrows + private void setCachedConnections(final String dsName, final int connectionSize) { + Multimap cachedConnections = HashMultimap.create(); + cachedConnections.putAll(dsName, mockNewConnections(connectionSize)); + Field field = backendConnection.getClass().getDeclaredField("cachedConnections"); + field.setAccessible(true); + field.set(backendConnection, cachedConnections); + } } From 8f2f8feed16948e0d326080b9eb2c9445bf7bad9 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Sat, 17 Nov 2018 10:50:09 +0800 Subject: [PATCH 009/113] #1238 Fill BackendConnectionTest.assertGetConnectionSizeGreaterThanCache. --- .../backend/jdbc/connection/BackendConnectionTest.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java index 5d924d2d0a371..a225da0e0a913 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java @@ -79,8 +79,12 @@ public void assertGetConnectionSizeLessThanCache() throws SQLException { } @Test - public void assertGetConnectionSizeGreaterThanCache() { - + public void assertGetConnectionSizeGreaterThanCache() throws SQLException { + setCachedConnections("ds1", 10); + when(backendDataSource.getConnections((ConnectionMode) any(), anyString(), eq(2))).thenReturn(mockNewConnections(2)); + List actualConnections = backendConnection.getConnections(ConnectionMode.MEMORY_STRICTLY, "ds1", 12); + assertThat(actualConnections.size(), is(12)); + assertThat(backendConnection.getConnectionSize(), is(12)); } @Test From eee7973f13ea9d34dead52b5665da0f3a1d14cd0 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Sat, 17 Nov 2018 10:51:11 +0800 Subject: [PATCH 010/113] #1238 Remove assertGetConnectionSizeIsOne, should verify in BackendDataSourceTest. --- .../backend/jdbc/connection/BackendConnectionTest.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java index a225da0e0a913..1cca6f3e2e912 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java @@ -87,11 +87,6 @@ public void assertGetConnectionSizeGreaterThanCache() throws SQLException { assertThat(backendConnection.getConnectionSize(), is(12)); } - @Test - public void assertGetConnectionSizeIsOne() { - - } - @Test public void assertMultiThreadGetConnection() { From 01e4da76a3773d832ddd7cf99da8cde16b0ab577 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Sat, 17 Nov 2018 10:57:05 +0800 Subject: [PATCH 011/113] #1238 Fill BackendConnectionTest.assertMultiThreadGetConnection. --- .../connection/BackendConnectionTest.java | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java index 1cca6f3e2e912..91e42462de33c 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java @@ -88,8 +88,38 @@ public void assertGetConnectionSizeGreaterThanCache() throws SQLException { } @Test + @SneakyThrows public void assertMultiThreadGetConnection() { - + setCachedConnections("ds1", 10); + when(backendDataSource.getConnections((ConnectionMode) any(), anyString(), eq(2))).thenReturn(mockNewConnections(2)); + Thread thread1 = new Thread(new Runnable() { + @Override + public void run() { + try { + List actualConnections = backendConnection.getConnections(ConnectionMode.MEMORY_STRICTLY, "ds1", 12); + assertThat(actualConnections.size(), is(12)); + assertThat(backendConnection.getConnectionSize(), is(12)); + } catch (SQLException e) { + e.printStackTrace(); + } + } + }); + Thread thread2 = new Thread(new Runnable() { + @Override + public void run() { + try { + List actualConnections = backendConnection.getConnections(ConnectionMode.MEMORY_STRICTLY, "ds1", 12); + assertThat(actualConnections.size(), is(12)); + assertThat(backendConnection.getConnectionSize(), is(12)); + } catch (SQLException e) { + e.printStackTrace(); + } + } + }); + thread1.start(); + thread2.start(); + thread1.join(); + thread2.join(); } private List mockNewConnections(final int connectionSize) { From cf8debe84515fc38a9cb4b2b6b898fa0bfc0ea12 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Sat, 17 Nov 2018 11:16:28 +0800 Subject: [PATCH 012/113] #1238 Refactor assertMultiThreadGetConnection. --- .../connection/BackendConnectionTest.java | 23 ++++++++----------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java index 91e42462de33c..e2d49762d7572 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java @@ -95,25 +95,13 @@ public void assertMultiThreadGetConnection() { Thread thread1 = new Thread(new Runnable() { @Override public void run() { - try { - List actualConnections = backendConnection.getConnections(ConnectionMode.MEMORY_STRICTLY, "ds1", 12); - assertThat(actualConnections.size(), is(12)); - assertThat(backendConnection.getConnectionSize(), is(12)); - } catch (SQLException e) { - e.printStackTrace(); - } + assertOneThreadResult(); } }); Thread thread2 = new Thread(new Runnable() { @Override public void run() { - try { - List actualConnections = backendConnection.getConnections(ConnectionMode.MEMORY_STRICTLY, "ds1", 12); - assertThat(actualConnections.size(), is(12)); - assertThat(backendConnection.getConnectionSize(), is(12)); - } catch (SQLException e) { - e.printStackTrace(); - } + assertOneThreadResult(); } }); thread1.start(); @@ -122,6 +110,13 @@ public void run() { thread2.join(); } + @SneakyThrows + private void assertOneThreadResult() { + List actualConnections = backendConnection.getConnections(ConnectionMode.MEMORY_STRICTLY, "ds1", 12); + assertThat(actualConnections.size(), is(12)); + assertThat(backendConnection.getConnectionSize(), is(12)); + } + private List mockNewConnections(final int connectionSize) { List result = new ArrayList<>(); for (int i = 0; i < connectionSize; i++) { From 4990ef6658adacd29d3600ccd95096496bea29d8 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Sat, 17 Nov 2018 15:39:51 +0800 Subject: [PATCH 013/113] #1238 Make BackendConnection initialize when ChannelHandler was build. --- .../shardingproxy/frontend/common/FrontendHandler.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/frontend/common/FrontendHandler.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/frontend/common/FrontendHandler.java index e9d93fccdaf47..2a1cacdfde9ce 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/frontend/common/FrontendHandler.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/frontend/common/FrontendHandler.java @@ -34,8 +34,7 @@ public abstract class FrontendHandler extends ChannelInboundHandlerAdapter { private volatile boolean authorized; - @Setter - private volatile BackendConnection backendConnection; + private volatile BackendConnection backendConnection = new BackendConnection(); @Getter @Setter From 0bef18f5979d8658ddc7678567e46492094b88c3 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Sat, 17 Nov 2018 15:44:22 +0800 Subject: [PATCH 014/113] #1238 CommandExecutor get backendConnection from channel handler. --- .../shardingproxy/frontend/common/FrontendHandler.java | 1 + .../shardingproxy/frontend/mysql/CommandExecutor.java | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/frontend/common/FrontendHandler.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/frontend/common/FrontendHandler.java index 2a1cacdfde9ce..f378e5f1d715a 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/frontend/common/FrontendHandler.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/frontend/common/FrontendHandler.java @@ -34,6 +34,7 @@ public abstract class FrontendHandler extends ChannelInboundHandlerAdapter { private volatile boolean authorized; + @Getter private volatile BackendConnection backendConnection = new BackendConnection(); @Getter diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/frontend/mysql/CommandExecutor.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/frontend/mysql/CommandExecutor.java index 6ec5221fca49c..75089260342ea 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/frontend/mysql/CommandExecutor.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/frontend/mysql/CommandExecutor.java @@ -61,8 +61,7 @@ public void run() { rootInvokeHook.start(); int connectionSize = 0; try (MySQLPacketPayload payload = new MySQLPacketPayload(message); - BackendConnection backendConnection = new BackendConnection()) { - frontendHandler.setBackendConnection(backendConnection); + BackendConnection backendConnection = frontendHandler.getBackendConnection()) { CommandPacket commandPacket = getCommandPacket(payload, backendConnection, frontendHandler); Optional responsePackets = commandPacket.execute(); if (!responsePackets.isPresent()) { From 35b8be92f9f662f8c33e8388d4e475a890ad1789 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Sat, 17 Nov 2018 15:48:45 +0800 Subject: [PATCH 015/113] #1238 Add init test class of JDBCBackendDataSourceTest. --- .../datasource/JDBCBackendDataSourceTest.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/datasource/JDBCBackendDataSourceTest.java diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/datasource/JDBCBackendDataSourceTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/datasource/JDBCBackendDataSourceTest.java new file mode 100644 index 0000000000000..1f9a518c61693 --- /dev/null +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/datasource/JDBCBackendDataSourceTest.java @@ -0,0 +1,21 @@ +/* + * Copyright 2016-2018 shardingsphere.io. + *

+ * Licensed 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 io.shardingsphere.shardingproxy.backend.jdbc.datasource; + +public class JDBCBackendDataSourceTest { +} From 9193d1cb3dc7fd88aa5669fe8b6d1126704a5d7a Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Sat, 17 Nov 2018 16:13:48 +0800 Subject: [PATCH 016/113] #1238 Clear cachedConnection while current request ended. --- .../backend/jdbc/connection/BackendConnection.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index cfd25adbc001e..b46207de231ae 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -147,6 +147,7 @@ private Collection closeResultSets() { result.add(ex); } } + cachedResultSets.clear(); return result; } @@ -159,6 +160,7 @@ private Collection closeStatements() { result.add(ex); } } + cachedStatements.clear(); return result; } @@ -171,6 +173,7 @@ private Collection closeConnections() { result.add(ex); } } + cachedConnections.clear(); return result; } From 84ab39663d5c8763698004070b9b1002f8270a9c Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Sat, 17 Nov 2018 17:21:32 +0800 Subject: [PATCH 017/113] #1238 Remove closeResultSets and closeStatements. --- .../backend/jdbc/connection/BackendConnection.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index b46207de231ae..eeedc198588d7 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -131,8 +131,6 @@ public void cancel() { @Override public void close() throws SQLException { Collection exceptions = new LinkedList<>(); - exceptions.addAll(closeResultSets()); - exceptions.addAll(closeStatements()); exceptions.addAll(closeConnections()); MasterVisitedManager.clear(); throwSQLExceptionIfNecessary(exceptions); From faf83d9f39029fc42fc0cfbfee2e861085aa1843 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Sat, 17 Nov 2018 17:30:58 +0800 Subject: [PATCH 018/113] #1238 Add BackendConnection.commit(). --- .../jdbc/connection/BackendConnection.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index eeedc198588d7..88a8a533a3391 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -136,6 +136,17 @@ public void close() throws SQLException { throwSQLExceptionIfNecessary(exceptions); } + /** + * Do commit. + * + * @throws SQLException SQL exception + */ + public void commit() throws SQLException { + Collection exceptions = new LinkedList<>(); + exceptions.addAll(commitConnections()); + throwSQLExceptionIfNecessary(exceptions); + } + private Collection closeResultSets() { Collection result = new LinkedList<>(); for (ResultSet each : cachedResultSets) { @@ -175,6 +186,19 @@ private Collection closeConnections() { return result; } + private Collection commitConnections() { + Collection result = new LinkedList<>(); + for (Connection each : cachedConnections.values()) { + try { + each.commit(); + } catch (SQLException ex) { + result.add(ex); + } + } + cachedConnections.clear(); + return result; + } + private void throwSQLExceptionIfNecessary(final Collection exceptions) throws SQLException { if (exceptions.isEmpty()) { return; From 416e2c06f56d2362c1e4d6282a0087167ea729de Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Sat, 17 Nov 2018 17:32:54 +0800 Subject: [PATCH 019/113] #1238 Add BackendConnection.rollback(). --- .../jdbc/connection/BackendConnection.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index 88a8a533a3391..a01439ad83dc0 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -147,6 +147,17 @@ public void commit() throws SQLException { throwSQLExceptionIfNecessary(exceptions); } + /** + * Do rollback. + * + * @throws SQLException SQL exception + */ + public void rollback() throws SQLException { + Collection exceptions = new LinkedList<>(); + exceptions.addAll(rollbackConnections()); + throwSQLExceptionIfNecessary(exceptions); + } + private Collection closeResultSets() { Collection result = new LinkedList<>(); for (ResultSet each : cachedResultSets) { @@ -199,6 +210,19 @@ private Collection commitConnections() { return result; } + private Collection rollbackConnections() { + Collection result = new LinkedList<>(); + for (Connection each : cachedConnections.values()) { + try { + each.rollback(); + } catch (SQLException ex) { + result.add(ex); + } + } + cachedConnections.clear(); + return result; + } + private void throwSQLExceptionIfNecessary(final Collection exceptions) throws SQLException { if (exceptions.isEmpty()) { return; From 297cf32ea49d518cf8f9d6564d07002659fdb75f Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Sat, 17 Nov 2018 18:08:40 +0800 Subject: [PATCH 020/113] #1238 Add MethodInvocation. --- .../jdbc/connection/MethodInvocation.java | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/MethodInvocation.java diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/MethodInvocation.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/MethodInvocation.java new file mode 100644 index 0000000000000..733dd7d521482 --- /dev/null +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/MethodInvocation.java @@ -0,0 +1,49 @@ +/* + * Copyright 2016-2018 shardingsphere.io. + *

+ * Licensed 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 io.shardingsphere.shardingproxy.backend.jdbc.connection; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; + +import java.lang.reflect.Method; + +/** + * Reflective method invocation. + * + * @author zhaojun + */ +@RequiredArgsConstructor +public class MethodInvocation { + + @Getter + private final Method method; + + @Getter + private final Object[] arguments; + + /** + * Invoke method. + * + * @param target target object + */ + @SneakyThrows + public void invoke(final Object target) { + method.invoke(target, arguments); + } +} From 286b586bc8d835c0a7a418989cd5f3af6f87fb29 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Sat, 17 Nov 2018 18:16:35 +0800 Subject: [PATCH 021/113] #1238 Add recordMethodInvocation for BackendConnection. --- .../backend/jdbc/connection/BackendConnection.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index a01439ad83dc0..0d67e3bf5f7aa 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -25,6 +25,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import lombok.SneakyThrows; import java.sql.Connection; import java.sql.ResultSet; @@ -55,6 +56,8 @@ public final class BackendConnection implements AutoCloseable { private final Collection cachedResultSets = new CopyOnWriteArrayList<>(); + private final Collection methodInvocations = new ArrayList<>(); + /** * Get connection size. * @@ -233,4 +236,9 @@ private void throwSQLExceptionIfNecessary(final Collection excepti } throw ex; } + + @SneakyThrows + private void recordMethodInvocation(final Class targetClass, final String methodName, final Class[] argumentTypes, final Object[] arguments) { + methodInvocations.add(new MethodInvocation(targetClass.getMethod(methodName, argumentTypes), arguments)); + } } From 45efc13c99e50e1e36aacbb49349b3a17a7936e6 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Sat, 17 Nov 2018 18:21:22 +0800 Subject: [PATCH 022/113] #1238 BackendConnection.setAutoCommit(). --- .../backend/jdbc/connection/BackendConnection.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index 0d67e3bf5f7aa..b068b857262f2 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -139,6 +139,10 @@ public void close() throws SQLException { throwSQLExceptionIfNecessary(exceptions); } + public void setAutoCommit(final boolean autoCommit) { + recordMethodInvocation(Connection.class, "setAutoCommit", new Class[]{boolean.class}, new Object[]{autoCommit}); + } + /** * Do commit. * From 830f06a63f5121365f9ebcdd8099881537cf0f4f Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Sat, 17 Nov 2018 18:23:19 +0800 Subject: [PATCH 023/113] #1238 for checkstyle. --- .../backend/jdbc/connection/BackendConnection.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index b068b857262f2..2f25423d36351 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -139,6 +139,11 @@ public void close() throws SQLException { throwSQLExceptionIfNecessary(exceptions); } + /** + * set auto commit. + * + * @param autoCommit auto commit + */ public void setAutoCommit(final boolean autoCommit) { recordMethodInvocation(Connection.class, "setAutoCommit", new Class[]{boolean.class}, new Object[]{autoCommit}); } From 0dc0211a6e93a5fd2a67cfec8a9f9e9c23cfc0b0 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Sat, 17 Nov 2018 18:24:59 +0800 Subject: [PATCH 024/113] #1238 BackendConnection.replayMethodsInvocation. --- .../backend/jdbc/connection/BackendConnection.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index 2f25423d36351..cf13568f2cc65 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -250,4 +250,10 @@ private void throwSQLExceptionIfNecessary(final Collection excepti private void recordMethodInvocation(final Class targetClass, final String methodName, final Class[] argumentTypes, final Object[] arguments) { methodInvocations.add(new MethodInvocation(targetClass.getMethod(methodName, argumentTypes), arguments)); } + + private void replayMethodsInvocation(final Object target) { + for (MethodInvocation each : methodInvocations) { + each.invoke(target); + } + } } From 0d70ce31c8c74cf7a8248241cbe7ad72c7658939 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Sat, 17 Nov 2018 18:32:43 +0800 Subject: [PATCH 025/113] #1238 Add BackendConnection.createConnections. --- .../backend/jdbc/connection/BackendConnection.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index cf13568f2cc65..ef74703924248 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -101,6 +101,14 @@ public List getConnections(final ConnectionMode connectionMode, fina return result; } + private Collection createConnections(final ConnectionMode connectionMode, final String dataSourceName, final int connectionSize) throws SQLException { + List result = logicSchema.getBackendDataSource().getConnections(connectionMode, dataSourceName, connectionSize); + for (Connection each : result) { + replayMethodsInvocation(each); + } + return result; + } + /** * Add statement. * From 7ae031fbd6d6947aebd056d8c03f932abb935d56 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Sat, 17 Nov 2018 18:35:13 +0800 Subject: [PATCH 026/113] #1238 Refactor BackendConnection.getConnections(). --- .../backend/jdbc/connection/BackendConnection.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index ef74703924248..f9a43ed722c35 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -87,13 +87,13 @@ public List getConnections(final ConnectionMode connectionMode, fina } else if (!connections.isEmpty()) { result = new ArrayList<>(connectionSize); result.addAll(connections); - List newConnections = logicSchema.getBackendDataSource().getConnections(connectionMode, dataSourceName, connectionSize - connections.size()); + List newConnections = createNewConnections(connectionMode, dataSourceName, connectionSize - connections.size()); result.addAll(newConnections); synchronized (cachedConnections) { cachedConnections.putAll(dataSourceName, newConnections); } } else { - result = new ArrayList<>(logicSchema.getBackendDataSource().getConnections(connectionMode, dataSourceName, connectionSize)); + result = createNewConnections(connectionMode, dataSourceName, connectionSize); synchronized (cachedConnections) { cachedConnections.putAll(dataSourceName, result); } @@ -101,7 +101,7 @@ public List getConnections(final ConnectionMode connectionMode, fina return result; } - private Collection createConnections(final ConnectionMode connectionMode, final String dataSourceName, final int connectionSize) throws SQLException { + private List createNewConnections(final ConnectionMode connectionMode, final String dataSourceName, final int connectionSize) throws SQLException { List result = logicSchema.getBackendDataSource().getConnections(connectionMode, dataSourceName, connectionSize); for (Connection each : result) { replayMethodsInvocation(each); From 13c7bae790d7da5ae519c9a15decd94fbcf35ca1 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Sat, 17 Nov 2018 18:47:26 +0800 Subject: [PATCH 027/113] #1238 Add ConnectionStatus enum for BackendConnection. --- .../jdbc/connection/ConnectionStatus.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/ConnectionStatus.java diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/ConnectionStatus.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/ConnectionStatus.java new file mode 100644 index 0000000000000..0270f59e8bc27 --- /dev/null +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/ConnectionStatus.java @@ -0,0 +1,28 @@ +/* + * Copyright 2016-2018 shardingsphere.io. + *

+ * Licensed 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 io.shardingsphere.shardingproxy.backend.jdbc.connection; + +/** + * Connection status. + * + * @author zhaojun + */ +public enum ConnectionStatus { + + INIT, RUNNING, TRANSACTION, TERMINATED +} From d9f211ddc15edf7a4f5b24d39b13ccedb2ffb72a Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Sat, 17 Nov 2018 18:56:41 +0800 Subject: [PATCH 028/113] #1238 Add status for BackendConnection. --- .../backend/jdbc/connection/BackendConnection.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index f9a43ed722c35..ab415dd863fd7 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -58,6 +58,8 @@ public final class BackendConnection implements AutoCloseable { private final Collection methodInvocations = new ArrayList<>(); + private ConnectionStatus status = ConnectionStatus.INIT; + /** * Get connection size. * @@ -77,6 +79,7 @@ public int getConnectionSize() { * @throws SQLException SQL exception */ public List getConnections(final ConnectionMode connectionMode, final String dataSourceName, final int connectionSize) throws SQLException { + status = ConnectionStatus.RUNNING; Collection connections; synchronized (cachedConnections) { connections = cachedConnections.get(dataSourceName); @@ -153,6 +156,7 @@ public void close() throws SQLException { * @param autoCommit auto commit */ public void setAutoCommit(final boolean autoCommit) { + status = ConnectionStatus.TRANSACTION; recordMethodInvocation(Connection.class, "setAutoCommit", new Class[]{boolean.class}, new Object[]{autoCommit}); } @@ -165,6 +169,7 @@ public void commit() throws SQLException { Collection exceptions = new LinkedList<>(); exceptions.addAll(commitConnections()); throwSQLExceptionIfNecessary(exceptions); + status = ConnectionStatus.TERMINATED; } /** @@ -176,6 +181,7 @@ public void rollback() throws SQLException { Collection exceptions = new LinkedList<>(); exceptions.addAll(rollbackConnections()); throwSQLExceptionIfNecessary(exceptions); + status = ConnectionStatus.TERMINATED; } private Collection closeResultSets() { From 962958eae2c00f4fc1742d333effffdb6da523e7 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Sun, 18 Nov 2018 11:50:34 +0800 Subject: [PATCH 029/113] #1238 Clear cachedConnections while close(). --- .../backend/jdbc/connection/BackendConnection.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index ab415dd863fd7..fb8e9deba53e8 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -145,8 +145,12 @@ public void cancel() { @Override public void close() throws SQLException { Collection exceptions = new LinkedList<>(); - exceptions.addAll(closeConnections()); MasterVisitedManager.clear(); + if (ConnectionStatus.TERMINATED == status) { + exceptions.addAll(closeConnections()); + cachedConnections.clear(); + methodInvocations.clear(); + } throwSQLExceptionIfNecessary(exceptions); } @@ -219,7 +223,6 @@ private Collection closeConnections() { result.add(ex); } } - cachedConnections.clear(); return result; } @@ -232,7 +235,6 @@ private Collection commitConnections() { result.add(ex); } } - cachedConnections.clear(); return result; } @@ -245,7 +247,6 @@ private Collection rollbackConnections() { result.add(ex); } } - cachedConnections.clear(); return result; } From 4acb2ab287e0d43e43ae3ce4c6b890cc48d4b128 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Sun, 18 Nov 2018 11:57:51 +0800 Subject: [PATCH 030/113] #1238 Add backendConnection property in ComQueryPacket. --- .../mysql/packet/command/query/text/query/ComQueryPacket.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacket.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacket.java index edf2f69eac820..e5912ab1295ff 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacket.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacket.java @@ -68,9 +68,12 @@ public final class ComQueryPacket implements QueryCommandPacket { private final TransactionType transactionType; + private final BackendConnection backendConnection; + public ComQueryPacket(final int sequenceId, final int connectionId, final MySQLPacketPayload payload, final BackendConnection backendConnection, final FrontendHandler frontendHandler) { this.sequenceId = sequenceId; sql = payload.readStringEOF(); + this.backendConnection = backendConnection; backendHandler = BackendHandlerFactory.createBackendHandler(connectionId, sequenceId, sql, backendConnection, DatabaseType.MySQL, frontendHandler); transactionType = GlobalRegistry.getInstance().getTransactionType(); shardingTransactionHandler = ShardingTransactionHandlerRegistry.getInstance().getHandler(transactionType); @@ -85,6 +88,7 @@ public ComQueryPacket(final int sequenceId, final String sql) { transactionType = GlobalRegistry.getInstance().getTransactionType(); backendHandler = null; shardingTransactionHandler = null; + this.backendConnection = null; } @Override From f007b54abdf67001e370ced81076c1f12d8f70e7 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Mon, 19 Nov 2018 11:24:27 +0800 Subject: [PATCH 031/113] #1238 Add Local transaction for ComQueryPacket. --- .../query/text/query/ComQueryPacket.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacket.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacket.java index e5912ab1295ff..92ac6fcde4840 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacket.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacket.java @@ -42,6 +42,7 @@ import io.shardingsphere.spi.transaction.ShardingTransactionHandler; import io.shardingsphere.spi.transaction.ShardingTransactionHandlerRegistry; import lombok.Getter; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import java.sql.SQLException; @@ -98,6 +99,7 @@ public void write(final MySQLPacketPayload payload) { } @Override + @SneakyThrows public Optional execute() { log.debug("COM_QUERY received for Sharding-Proxy: {}", sql); if (GlobalRegistry.getInstance().isCircuitBreak()) { @@ -107,7 +109,20 @@ public Optional execute() { if (!operationType.isPresent()) { return Optional.of(backendHandler.execute()); } - if (TransactionType.XA == transactionType) { + if (TransactionType.LOCAL == transactionType) { + switch (operationType.get()) { + case BEGIN: + backendConnection.setAutoCommit(true); + break; + case COMMIT: + backendConnection.commit(); + break; + case ROLLBACK: + backendConnection.rollback(); + break; + default: + } + } else if (TransactionType.XA == transactionType) { shardingTransactionHandler.doInTransaction(new XATransactionEvent(operationType.get())); } // TODO :zhaojun do not send TCL to backend, send when local transaction ready From d2a84d6f5a40262e2938a70bf40e259ca896da18 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Mon, 19 Nov 2018 12:17:19 +0800 Subject: [PATCH 032/113] #1238 Clear cache while start new transaction. --- .../backend/jdbc/connection/BackendConnection.java | 1 + .../mysql/packet/command/query/text/query/ComQueryPacket.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index fb8e9deba53e8..e7965be60f61a 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -160,6 +160,7 @@ public void close() throws SQLException { * @param autoCommit auto commit */ public void setAutoCommit(final boolean autoCommit) { + cachedConnections.clear(); status = ConnectionStatus.TRANSACTION; recordMethodInvocation(Connection.class, "setAutoCommit", new Class[]{boolean.class}, new Object[]{autoCommit}); } diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacket.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacket.java index 92ac6fcde4840..03d8f49507555 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacket.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacket.java @@ -112,7 +112,7 @@ public Optional execute() { if (TransactionType.LOCAL == transactionType) { switch (operationType.get()) { case BEGIN: - backendConnection.setAutoCommit(true); + backendConnection.setAutoCommit(false); break; case COMMIT: backendConnection.commit(); From 5d1010b128f4de922f0f4df030844711296c8559 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Mon, 19 Nov 2018 15:21:31 +0800 Subject: [PATCH 033/113] #1238 Close statement and resultSet for release current transaction resource. --- .../backend/jdbc/connection/BackendConnection.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index e7965be60f61a..7ffa1e659c5b5 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -146,6 +146,8 @@ public void cancel() { public void close() throws SQLException { Collection exceptions = new LinkedList<>(); MasterVisitedManager.clear(); + exceptions.addAll(closeStatements()); + exceptions.addAll(closeResultSets()); if (ConnectionStatus.TERMINATED == status) { exceptions.addAll(closeConnections()); cachedConnections.clear(); From 6c75dd0aef1be11ba4dc174fc5de7c46fe5f46ad Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Mon, 19 Nov 2018 18:34:36 +0800 Subject: [PATCH 034/113] #1238 Only change status to TRANSACTION while setAutoCommit was false. --- .../backend/jdbc/connection/BackendConnection.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index 7ffa1e659c5b5..ff408d72d5bb9 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -162,8 +162,10 @@ public void close() throws SQLException { * @param autoCommit auto commit */ public void setAutoCommit(final boolean autoCommit) { + if (!autoCommit) { + status = ConnectionStatus.TRANSACTION; + } cachedConnections.clear(); - status = ConnectionStatus.TRANSACTION; recordMethodInvocation(Connection.class, "setAutoCommit", new Class[]{boolean.class}, new Object[]{autoCommit}); } From 1bceae1076552d16a3ea2d66328d6adb42575e93 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Mon, 19 Nov 2018 18:35:12 +0800 Subject: [PATCH 035/113] #1238 Only execute commit while in TRANSACTION status. --- .../backend/jdbc/connection/BackendConnection.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index ff408d72d5bb9..48bd5196734a0 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -175,10 +175,12 @@ public void setAutoCommit(final boolean autoCommit) { * @throws SQLException SQL exception */ public void commit() throws SQLException { - Collection exceptions = new LinkedList<>(); - exceptions.addAll(commitConnections()); - throwSQLExceptionIfNecessary(exceptions); - status = ConnectionStatus.TERMINATED; + if (ConnectionStatus.TRANSACTION == status) { + Collection exceptions = new LinkedList<>(); + exceptions.addAll(commitConnections()); + throwSQLExceptionIfNecessary(exceptions); + status = ConnectionStatus.TERMINATED; + } } /** From 363fc2840cea182f1a90a28da4167e2442fb9ed8 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Mon, 19 Nov 2018 18:36:01 +0800 Subject: [PATCH 036/113] #1238 Only execute rollback while in TRANSACTION status. --- .../backend/jdbc/connection/BackendConnection.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index 48bd5196734a0..3b6e5b2418380 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -189,10 +189,12 @@ public void commit() throws SQLException { * @throws SQLException SQL exception */ public void rollback() throws SQLException { - Collection exceptions = new LinkedList<>(); - exceptions.addAll(rollbackConnections()); - throwSQLExceptionIfNecessary(exceptions); - status = ConnectionStatus.TERMINATED; + if (ConnectionStatus.TRANSACTION == status) { + Collection exceptions = new LinkedList<>(); + exceptions.addAll(rollbackConnections()); + throwSQLExceptionIfNecessary(exceptions); + status = ConnectionStatus.TERMINATED; + } } private Collection closeResultSets() { From 98a3c3c4cc880181a6abb396ef3eacdd3a5e7fa3 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Mon, 19 Nov 2018 18:44:23 +0800 Subject: [PATCH 037/113] #1238 Make transactionType bind with channel handler. --- .../backend/jdbc/connection/BackendConnection.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index 3b6e5b2418380..1f1ba1f7e3af2 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -20,7 +20,9 @@ import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import io.shardingsphere.core.constant.ConnectionMode; +import io.shardingsphere.core.constant.transaction.TransactionType; import io.shardingsphere.core.routing.router.masterslave.MasterVisitedManager; +import io.shardingsphere.shardingproxy.runtime.GlobalRegistry; import io.shardingsphere.shardingproxy.runtime.schema.LogicSchema; import lombok.Getter; import lombok.NoArgsConstructor; @@ -60,6 +62,8 @@ public final class BackendConnection implements AutoCloseable { private ConnectionStatus status = ConnectionStatus.INIT; + private final TransactionType transactionType = GlobalRegistry.getInstance().getTransactionType(); + /** * Get connection size. * From a528da2a6969d10040eb89b8589ea6745618d55c Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Mon, 19 Nov 2018 18:51:47 +0800 Subject: [PATCH 038/113] #1238 Add doInTransaction method in BackendConnection. --- .../jdbc/connection/BackendConnection.java | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index 1f1ba1f7e3af2..6fad1a6c91abd 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -17,13 +17,19 @@ package io.shardingsphere.shardingproxy.backend.jdbc.connection; +import com.google.common.base.Preconditions; import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import io.shardingsphere.core.constant.ConnectionMode; +import io.shardingsphere.core.constant.transaction.TransactionOperationType; import io.shardingsphere.core.constant.transaction.TransactionType; +import io.shardingsphere.core.event.transaction.ShardingTransactionEvent; +import io.shardingsphere.core.event.transaction.xa.XATransactionEvent; import io.shardingsphere.core.routing.router.masterslave.MasterVisitedManager; import io.shardingsphere.shardingproxy.runtime.GlobalRegistry; import io.shardingsphere.shardingproxy.runtime.schema.LogicSchema; +import io.shardingsphere.spi.transaction.ShardingTransactionHandler; +import io.shardingsphere.spi.transaction.ShardingTransactionHandlerRegistry; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -173,6 +179,35 @@ public void setAutoCommit(final boolean autoCommit) { recordMethodInvocation(Connection.class, "setAutoCommit", new Class[]{boolean.class}, new Object[]{autoCommit}); } + /** + * Execute transaction by operation type. + * + * @param operationType operation type + * @throws SQLException SQL exception + */ + public void doInTransactional(final TransactionOperationType operationType) throws SQLException { + ShardingTransactionHandler shardingTransactionHandler = ShardingTransactionHandlerRegistry.getInstance().getHandler(transactionType); + if (null != transactionType && transactionType != TransactionType.LOCAL) { + Preconditions.checkNotNull(shardingTransactionHandler, String.format("Cannot find transaction manager of [%s]", transactionType)); + } + if (TransactionType.LOCAL == transactionType) { + switch (operationType) { + case BEGIN: + setAutoCommit(false); + break; + case COMMIT: + commit(); + break; + case ROLLBACK: + rollback(); + break; + default: + } + } else if (TransactionType.XA == transactionType) { + shardingTransactionHandler.doInTransaction(new XATransactionEvent(operationType)); + } + } + /** * Do commit. * From fe774a5fed09984ee9baa5145bdcd4b3f7502f5f Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Mon, 19 Nov 2018 18:59:34 +0800 Subject: [PATCH 039/113] #1238 Refactor ComQueryPacket. --- .../query/text/query/ComQueryPacket.java | 35 +------------------ 1 file changed, 1 insertion(+), 34 deletions(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacket.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacket.java index 03d8f49507555..72b03193f1f63 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacket.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacket.java @@ -18,12 +18,8 @@ package io.shardingsphere.shardingproxy.transport.mysql.packet.command.query.text.query; import com.google.common.base.Optional; -import com.google.common.base.Preconditions; import io.shardingsphere.core.constant.DatabaseType; import io.shardingsphere.core.constant.transaction.TransactionOperationType; -import io.shardingsphere.core.constant.transaction.TransactionType; -import io.shardingsphere.core.event.transaction.ShardingTransactionEvent; -import io.shardingsphere.core.event.transaction.xa.XATransactionEvent; import io.shardingsphere.shardingproxy.backend.BackendHandler; import io.shardingsphere.shardingproxy.backend.BackendHandlerFactory; import io.shardingsphere.shardingproxy.backend.ResultPacket; @@ -39,8 +35,6 @@ import io.shardingsphere.shardingproxy.transport.mysql.packet.command.query.text.TextResultSetRowPacket; import io.shardingsphere.shardingproxy.transport.mysql.packet.generic.ErrPacket; import io.shardingsphere.shardingproxy.transport.mysql.packet.generic.OKPacket; -import io.shardingsphere.spi.transaction.ShardingTransactionHandler; -import io.shardingsphere.spi.transaction.ShardingTransactionHandlerRegistry; import lombok.Getter; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; @@ -65,10 +59,6 @@ public final class ComQueryPacket implements QueryCommandPacket { private final BackendHandler backendHandler; - private final ShardingTransactionHandler shardingTransactionHandler; - - private final TransactionType transactionType; - private final BackendConnection backendConnection; public ComQueryPacket(final int sequenceId, final int connectionId, final MySQLPacketPayload payload, final BackendConnection backendConnection, final FrontendHandler frontendHandler) { @@ -76,19 +66,12 @@ public ComQueryPacket(final int sequenceId, final int connectionId, final MySQLP sql = payload.readStringEOF(); this.backendConnection = backendConnection; backendHandler = BackendHandlerFactory.createBackendHandler(connectionId, sequenceId, sql, backendConnection, DatabaseType.MySQL, frontendHandler); - transactionType = GlobalRegistry.getInstance().getTransactionType(); - shardingTransactionHandler = ShardingTransactionHandlerRegistry.getInstance().getHandler(transactionType); - if (null != transactionType && transactionType != TransactionType.LOCAL) { - Preconditions.checkNotNull(shardingTransactionHandler, String.format("Cannot find transaction manager of [%s]", transactionType)); - } } public ComQueryPacket(final int sequenceId, final String sql) { this.sequenceId = sequenceId; this.sql = sql; - transactionType = GlobalRegistry.getInstance().getTransactionType(); backendHandler = null; - shardingTransactionHandler = null; this.backendConnection = null; } @@ -109,23 +92,7 @@ public Optional execute() { if (!operationType.isPresent()) { return Optional.of(backendHandler.execute()); } - if (TransactionType.LOCAL == transactionType) { - switch (operationType.get()) { - case BEGIN: - backendConnection.setAutoCommit(false); - break; - case COMMIT: - backendConnection.commit(); - break; - case ROLLBACK: - backendConnection.rollback(); - break; - default: - } - } else if (TransactionType.XA == transactionType) { - shardingTransactionHandler.doInTransaction(new XATransactionEvent(operationType.get())); - } - // TODO :zhaojun do not send TCL to backend, send when local transaction ready + backendConnection.doInTransactional(operationType.get()); return Optional.of(new CommandResponsePackets(new OKPacket(1))); } From 2a66022d294286010c4a7367bed51917949bbc8f Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Mon, 19 Nov 2018 19:27:08 +0800 Subject: [PATCH 040/113] #1238 Revise ComQueryPacketTest. --- .../backend/jdbc/connection/BackendConnection.java | 4 +++- .../query/text/query/ComQueryPacketTest.java | 14 +++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index 6fad1a6c91abd..a481af2ac40ce 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -68,7 +68,9 @@ public final class BackendConnection implements AutoCloseable { private ConnectionStatus status = ConnectionStatus.INIT; - private final TransactionType transactionType = GlobalRegistry.getInstance().getTransactionType(); + @Getter + @Setter + private TransactionType transactionType = GlobalRegistry.getInstance().getTransactionType(); /** * Get connection size. diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacketTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacketTest.java index 5990862889aa0..3d40c8f929dbb 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacketTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacketTest.java @@ -70,14 +70,14 @@ public final class ComQueryPacketTest { @Mock private MySQLPacketPayload payload; - @Mock - private BackendConnection backendConnection; + private BackendConnection backendConnection = new BackendConnection(); @Mock private FrontendHandler frontendHandler; @BeforeClass public static void init() { + setTransactionType(TransactionType.LOCAL); ShardingTransactionHandlerRegistry.load(); } @@ -108,13 +108,13 @@ private void setFrontendHandlerSchema() { } @SneakyThrows - private void setTransactionType(final TransactionType transactionType) { + private static void setTransactionType(final TransactionType transactionType) { Field field = GlobalRegistry.getInstance().getClass().getDeclaredField("shardingProperties"); field.setAccessible(true); field.set(GlobalRegistry.getInstance(), getShardingProperties(transactionType)); } - private ShardingProperties getShardingProperties(final TransactionType transactionType) { + private static ShardingProperties getShardingProperties(final TransactionType transactionType) { Properties props = new Properties(); props.setProperty(ShardingPropertiesConstant.PROXY_TRANSACTION_ENABLED.getKey(), String.valueOf(transactionType == TransactionType.XA)); return new ShardingProperties(props); @@ -171,7 +171,7 @@ public void assertExecuteTCLWithLocalTransaction() { @Test public void assertExecuteTCLWithXATransaction() { - setTransactionType(TransactionType.XA); + backendConnection.setTransactionType(TransactionType.XA); when(payload.readStringEOF()).thenReturn("COMMIT"); ComQueryPacket packet = new ComQueryPacket(1, 1000, payload, backendConnection, frontendHandler); Optional actual = packet.execute(); @@ -181,8 +181,8 @@ public void assertExecuteTCLWithXATransaction() { } @Test - public void assertExecuteRollbackWithXATransaction() throws SQLException { - setTransactionType(TransactionType.XA); + public void assertExecuteRollbackWithXATransaction() { + backendConnection.setTransactionType(TransactionType.XA); when(payload.readStringEOF()).thenReturn("COMMIT"); ComQueryPacket packet = new ComQueryPacket(1, 1000, payload, backendConnection, frontendHandler); Optional actual = packet.execute(); From ecbc10219129d8a760c9a9dae475ef82a3f31036 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Mon, 19 Nov 2018 19:27:48 +0800 Subject: [PATCH 041/113] #1238 Revise ComQueryPacketTest. --- .../packet/command/query/text/query/ComQueryPacketTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacketTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacketTest.java index 3d40c8f929dbb..962bb2848bcfd 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacketTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacketTest.java @@ -172,12 +172,12 @@ public void assertExecuteTCLWithLocalTransaction() { @Test public void assertExecuteTCLWithXATransaction() { backendConnection.setTransactionType(TransactionType.XA); - when(payload.readStringEOF()).thenReturn("COMMIT"); + when(payload.readStringEOF()).thenReturn("ROLLBACK"); ComQueryPacket packet = new ComQueryPacket(1, 1000, payload, backendConnection, frontendHandler); Optional actual = packet.execute(); assertTrue(actual.isPresent()); assertOKPacket(actual.get()); - assertThat(FixedXAShardingTransactionHandler.getInvokes().get("commit"), instanceOf(ShardingTransactionEvent.class)); + assertThat(FixedXAShardingTransactionHandler.getInvokes().get("rollback"), instanceOf(ShardingTransactionEvent.class)); } @Test From c143d87f181419c92e97c0489def970d294eacb3 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Mon, 19 Nov 2018 19:36:05 +0800 Subject: [PATCH 042/113] #1238 only judge status before doInTransactional(). --- .../jdbc/connection/BackendConnection.java | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index a481af2ac40ce..6c713217eb925 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -173,7 +173,7 @@ public void close() throws SQLException { * * @param autoCommit auto commit */ - public void setAutoCommit(final boolean autoCommit) { + private void setAutoCommit(final boolean autoCommit) { if (!autoCommit) { status = ConnectionStatus.TRANSACTION; } @@ -188,6 +188,9 @@ public void setAutoCommit(final boolean autoCommit) { * @throws SQLException SQL exception */ public void doInTransactional(final TransactionOperationType operationType) throws SQLException { + if (ConnectionStatus.TRANSACTION != status) { + return; + } ShardingTransactionHandler shardingTransactionHandler = ShardingTransactionHandlerRegistry.getInstance().getHandler(transactionType); if (null != transactionType && transactionType != TransactionType.LOCAL) { Preconditions.checkNotNull(shardingTransactionHandler, String.format("Cannot find transaction manager of [%s]", transactionType)); @@ -215,13 +218,11 @@ public void doInTransactional(final TransactionOperationType operationType) thro * * @throws SQLException SQL exception */ - public void commit() throws SQLException { - if (ConnectionStatus.TRANSACTION == status) { - Collection exceptions = new LinkedList<>(); - exceptions.addAll(commitConnections()); - throwSQLExceptionIfNecessary(exceptions); - status = ConnectionStatus.TERMINATED; - } + private void commit() throws SQLException { + Collection exceptions = new LinkedList<>(); + exceptions.addAll(commitConnections()); + throwSQLExceptionIfNecessary(exceptions); + status = ConnectionStatus.TERMINATED; } /** @@ -229,13 +230,11 @@ public void commit() throws SQLException { * * @throws SQLException SQL exception */ - public void rollback() throws SQLException { - if (ConnectionStatus.TRANSACTION == status) { - Collection exceptions = new LinkedList<>(); - exceptions.addAll(rollbackConnections()); - throwSQLExceptionIfNecessary(exceptions); - status = ConnectionStatus.TERMINATED; - } + private void rollback() throws SQLException { + Collection exceptions = new LinkedList<>(); + exceptions.addAll(rollbackConnections()); + throwSQLExceptionIfNecessary(exceptions); + status = ConnectionStatus.TERMINATED; } private Collection closeResultSets() { From 121bf128ada7b05db608a9159c773e78819929ef Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Mon, 19 Nov 2018 19:42:21 +0800 Subject: [PATCH 043/113] #1238 Add setConnectionStatus method. --- .../command/query/text/query/ComQueryPacketTest.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacketTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacketTest.java index 962bb2848bcfd..f0f2ef3dcd6ea 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacketTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacketTest.java @@ -26,6 +26,7 @@ import io.shardingsphere.shardingproxy.backend.BackendHandler; import io.shardingsphere.shardingproxy.backend.ResultPacket; import io.shardingsphere.shardingproxy.backend.jdbc.connection.BackendConnection; +import io.shardingsphere.shardingproxy.backend.jdbc.connection.ConnectionStatus; import io.shardingsphere.shardingproxy.frontend.common.FrontendHandler; import io.shardingsphere.shardingproxy.runtime.GlobalRegistry; import io.shardingsphere.shardingproxy.runtime.schema.ShardingSchema; @@ -162,6 +163,7 @@ private void setBackendHandler(final ComQueryPacket packet, final BackendHandler @Test public void assertExecuteTCLWithLocalTransaction() { setTransactionType(TransactionType.LOCAL); + setConnectionStatus(ConnectionStatus.TRANSACTION); when(payload.readStringEOF()).thenReturn("COMMIT"); ComQueryPacket packet = new ComQueryPacket(1, 1000, payload, backendConnection, frontendHandler); Optional actual = packet.execute(); @@ -172,6 +174,7 @@ public void assertExecuteTCLWithLocalTransaction() { @Test public void assertExecuteTCLWithXATransaction() { backendConnection.setTransactionType(TransactionType.XA); + setConnectionStatus(ConnectionStatus.TRANSACTION); when(payload.readStringEOF()).thenReturn("ROLLBACK"); ComQueryPacket packet = new ComQueryPacket(1, 1000, payload, backendConnection, frontendHandler); Optional actual = packet.execute(); @@ -183,6 +186,7 @@ public void assertExecuteTCLWithXATransaction() { @Test public void assertExecuteRollbackWithXATransaction() { backendConnection.setTransactionType(TransactionType.XA); + setConnectionStatus(ConnectionStatus.TRANSACTION); when(payload.readStringEOF()).thenReturn("COMMIT"); ComQueryPacket packet = new ComQueryPacket(1, 1000, payload, backendConnection, frontendHandler); Optional actual = packet.execute(); @@ -191,6 +195,13 @@ public void assertExecuteRollbackWithXATransaction() { assertThat(FixedXAShardingTransactionHandler.getInvokes().get("commit"), instanceOf(ShardingTransactionEvent.class)); } + @SneakyThrows + private void setConnectionStatus(final ConnectionStatus status) { + Field field = backendConnection.getClass().getDeclaredField("status"); + field.setAccessible(true); + field.set(backendConnection, status); + } + private void assertOKPacket(final CommandResponsePackets actual) { assertThat(actual.getPackets().size(), is(1)); assertThat((actual.getPackets().iterator().next()).getSequenceId(), is(1)); From cb80da20fe97957a2fc23d21b9243bb8362f23be Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Mon, 19 Nov 2018 19:47:54 +0800 Subject: [PATCH 044/113] #1238 Revise doInTransactional --- .../jdbc/connection/BackendConnection.java | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index 6c713217eb925..fcfe95497a12f 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -188,9 +188,6 @@ private void setAutoCommit(final boolean autoCommit) { * @throws SQLException SQL exception */ public void doInTransactional(final TransactionOperationType operationType) throws SQLException { - if (ConnectionStatus.TRANSACTION != status) { - return; - } ShardingTransactionHandler shardingTransactionHandler = ShardingTransactionHandlerRegistry.getInstance().getHandler(transactionType); if (null != transactionType && transactionType != TransactionType.LOCAL) { Preconditions.checkNotNull(shardingTransactionHandler, String.format("Cannot find transaction manager of [%s]", transactionType)); @@ -219,10 +216,12 @@ public void doInTransactional(final TransactionOperationType operationType) thro * @throws SQLException SQL exception */ private void commit() throws SQLException { - Collection exceptions = new LinkedList<>(); - exceptions.addAll(commitConnections()); - throwSQLExceptionIfNecessary(exceptions); - status = ConnectionStatus.TERMINATED; + if (ConnectionStatus.TRANSACTION == status) { + Collection exceptions = new LinkedList<>(); + exceptions.addAll(commitConnections()); + throwSQLExceptionIfNecessary(exceptions); + status = ConnectionStatus.TERMINATED; + } } /** @@ -231,10 +230,12 @@ private void commit() throws SQLException { * @throws SQLException SQL exception */ private void rollback() throws SQLException { - Collection exceptions = new LinkedList<>(); - exceptions.addAll(rollbackConnections()); - throwSQLExceptionIfNecessary(exceptions); - status = ConnectionStatus.TERMINATED; + if (ConnectionStatus.TRANSACTION == status) { + Collection exceptions = new LinkedList<>(); + exceptions.addAll(rollbackConnections()); + throwSQLExceptionIfNecessary(exceptions); + status = ConnectionStatus.TERMINATED; + } } private Collection closeResultSets() { From feefa4f42aaefdfa9bf8ed5604d3a5a2348393ba Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Mon, 19 Nov 2018 22:15:57 +0800 Subject: [PATCH 045/113] #1238 Switch status to RUNNING while first getConnections. --- .../backend/jdbc/connection/BackendConnection.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index fcfe95497a12f..a0c6724937baa 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -91,7 +91,9 @@ public int getConnectionSize() { * @throws SQLException SQL exception */ public List getConnections(final ConnectionMode connectionMode, final String dataSourceName, final int connectionSize) throws SQLException { - status = ConnectionStatus.RUNNING; + if (ConnectionStatus.INIT == status || ConnectionStatus.TERMINATED == status) { + status = ConnectionStatus.RUNNING; + } Collection connections; synchronized (cachedConnections) { connections = cachedConnections.get(dataSourceName); From 73015c70535ecca96a9e1a4d8fa92bc92972ac1f Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Mon, 19 Nov 2018 22:17:36 +0800 Subject: [PATCH 046/113] #1238 Add init ProxyTransactionManager for BackendConnection. --- .../connection/ProxyTransactionManager.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/ProxyTransactionManager.java diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/ProxyTransactionManager.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/ProxyTransactionManager.java new file mode 100644 index 0000000000000..c6aae81afb246 --- /dev/null +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/ProxyTransactionManager.java @@ -0,0 +1,26 @@ +/* + * Copyright 2016-2018 shardingsphere.io. + *

+ * Licensed 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 io.shardingsphere.shardingproxy.backend.jdbc.connection; + +/** + * Proxy transaction manager. + * + * @author zhaojun + */ +public class ProxyTransactionManager { +} From a84f5c82eb07452507c77fb64f98f929ac682992 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Mon, 19 Nov 2018 22:37:08 +0800 Subject: [PATCH 047/113] #1238 Add ProxyTransactionManager implement. --- .../connection/ProxyTransactionManager.java | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/ProxyTransactionManager.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/ProxyTransactionManager.java index c6aae81afb246..3746dd844ed33 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/ProxyTransactionManager.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/ProxyTransactionManager.java @@ -17,10 +17,124 @@ package io.shardingsphere.shardingproxy.backend.jdbc.connection; +import com.google.common.base.Preconditions; +import io.shardingsphere.core.constant.transaction.TransactionOperationType; +import io.shardingsphere.core.constant.transaction.TransactionType; +import io.shardingsphere.core.event.transaction.ShardingTransactionEvent; +import io.shardingsphere.core.event.transaction.xa.XATransactionEvent; +import io.shardingsphere.spi.transaction.ShardingTransactionHandler; +import io.shardingsphere.spi.transaction.ShardingTransactionHandlerRegistry; +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.Collection; +import java.util.LinkedList; + /** * Proxy transaction manager. * * @author zhaojun */ +@RequiredArgsConstructor public class ProxyTransactionManager { + + private final BackendConnection connection; + + /** + * Handle proxy transaction. + * + * @param operationType transaction operation type + * @throws SQLException SQL Exception + */ + public void doInTransaction(final TransactionOperationType operationType) throws SQLException { + TransactionType transactionType = connection.getTransactionType(); + ShardingTransactionHandler shardingTransactionHandler = ShardingTransactionHandlerRegistry.getInstance().getHandler(transactionType); + if (null != transactionType && transactionType != TransactionType.LOCAL) { + Preconditions.checkNotNull(shardingTransactionHandler, String.format("Cannot find transaction manager of [%s]", transactionType)); + } + if (TransactionType.LOCAL == transactionType) { + switch (operationType) { + case BEGIN: + setAutoCommit(false); + break; + case COMMIT: + commit(); + break; + case ROLLBACK: + rollback(); + break; + default: + } + } else if (TransactionType.XA == transactionType) { + shardingTransactionHandler.doInTransaction(new XATransactionEvent(operationType)); + } + } + + private void setAutoCommit(final boolean autoCommit) { + if (!autoCommit) { + connection.setStatus(ConnectionStatus.TRANSACTION); + } + connection.getCachedConnections().clear(); + recordMethodInvocation(Connection.class, "setAutoCommit", new Class[]{boolean.class}, new Object[]{autoCommit}); + } + + private void commit() throws SQLException { + if (ConnectionStatus.TRANSACTION == connection.getStatus()) { + Collection exceptions = new LinkedList<>(); + exceptions.addAll(commitConnections()); + throwSQLExceptionIfNecessary(exceptions); + connection.setStatus(ConnectionStatus.TERMINATED); + } + } + + private void rollback() throws SQLException { + if (ConnectionStatus.TRANSACTION == connection.getStatus()) { + Collection exceptions = new LinkedList<>(); + exceptions.addAll(rollbackConnections()); + throwSQLExceptionIfNecessary(exceptions); + connection.setStatus(ConnectionStatus.TERMINATED); + } + } + + private Collection commitConnections() { + Collection result = new LinkedList<>(); + for (Connection each : connection.getCachedConnections().values()) { + try { + each.commit(); + } catch (SQLException ex) { + result.add(ex); + } + } + return result; + } + + private Collection rollbackConnections() { + Collection result = new LinkedList<>(); + for (Connection each : connection.getCachedConnections().values()) { + try { + each.rollback(); + } catch (SQLException ex) { + result.add(ex); + } + } + return result; + } + + private void throwSQLExceptionIfNecessary(final Collection exceptions) throws SQLException { + if (exceptions.isEmpty()) { + return; + } + SQLException ex = new SQLException(); + for (SQLException each : exceptions) { + ex.setNextException(each); + } + throw ex; + } + + @SneakyThrows + private void recordMethodInvocation(final Class targetClass, final String methodName, final Class[] argumentTypes, final Object[] arguments) { + connection.getMethodInvocations().add(new MethodInvocation(targetClass.getMethod(methodName, argumentTypes), arguments)); + } } From ddaf1f2ad6407c3bb4a306319390794d32894621 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Mon, 19 Nov 2018 22:42:20 +0800 Subject: [PATCH 048/113] #1238 Refactor ComQueryPacket Using ProxyTransactionManager. --- .../backend/jdbc/connection/BackendConnection.java | 4 ++-- .../packet/command/query/text/query/ComQueryPacket.java | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index a0c6724937baa..f8d85475479f7 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -52,9 +52,9 @@ * @author zhangliang */ @NoArgsConstructor +@Getter public final class BackendConnection implements AutoCloseable { - @Getter @Setter private LogicSchema logicSchema; @@ -66,9 +66,9 @@ public final class BackendConnection implements AutoCloseable { private final Collection methodInvocations = new ArrayList<>(); + @Setter private ConnectionStatus status = ConnectionStatus.INIT; - @Getter @Setter private TransactionType transactionType = GlobalRegistry.getInstance().getTransactionType(); diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacket.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacket.java index 72b03193f1f63..d530e88462282 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacket.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacket.java @@ -24,6 +24,7 @@ import io.shardingsphere.shardingproxy.backend.BackendHandlerFactory; import io.shardingsphere.shardingproxy.backend.ResultPacket; import io.shardingsphere.shardingproxy.backend.jdbc.connection.BackendConnection; +import io.shardingsphere.shardingproxy.backend.jdbc.connection.ProxyTransactionManager; import io.shardingsphere.shardingproxy.frontend.common.FrontendHandler; import io.shardingsphere.shardingproxy.runtime.GlobalRegistry; import io.shardingsphere.shardingproxy.transport.common.packet.DatabasePacket; @@ -59,20 +60,20 @@ public final class ComQueryPacket implements QueryCommandPacket { private final BackendHandler backendHandler; - private final BackendConnection backendConnection; + private final ProxyTransactionManager proxyTransactionManager; public ComQueryPacket(final int sequenceId, final int connectionId, final MySQLPacketPayload payload, final BackendConnection backendConnection, final FrontendHandler frontendHandler) { this.sequenceId = sequenceId; sql = payload.readStringEOF(); - this.backendConnection = backendConnection; backendHandler = BackendHandlerFactory.createBackendHandler(connectionId, sequenceId, sql, backendConnection, DatabaseType.MySQL, frontendHandler); + proxyTransactionManager = new ProxyTransactionManager(backendConnection); } public ComQueryPacket(final int sequenceId, final String sql) { this.sequenceId = sequenceId; this.sql = sql; backendHandler = null; - this.backendConnection = null; + this.proxyTransactionManager = null; } @Override @@ -92,7 +93,7 @@ public Optional execute() { if (!operationType.isPresent()) { return Optional.of(backendHandler.execute()); } - backendConnection.doInTransactional(operationType.get()); + proxyTransactionManager.doInTransaction(operationType.get()); return Optional.of(new CommandResponsePackets(new OKPacket(1))); } From c12200cf98e2a85c54ebdb0ec6a558f5d8c37c6d Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Mon, 19 Nov 2018 22:44:16 +0800 Subject: [PATCH 049/113] #1238 Refactor ComQueryPacket ProxyTransactionManager => BackendTransactionManager. --- ...tionManager.java => BackendTransactionManager.java} | 2 +- .../command/query/text/query/ComQueryPacket.java | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) rename sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/{ProxyTransactionManager.java => BackendTransactionManager.java} (99%) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/ProxyTransactionManager.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManager.java similarity index 99% rename from sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/ProxyTransactionManager.java rename to sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManager.java index 3746dd844ed33..056f4c4a0b09a 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/ProxyTransactionManager.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManager.java @@ -38,7 +38,7 @@ * @author zhaojun */ @RequiredArgsConstructor -public class ProxyTransactionManager { +public class BackendTransactionManager { private final BackendConnection connection; diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacket.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacket.java index d530e88462282..24e3cf955bb84 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacket.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacket.java @@ -24,7 +24,7 @@ import io.shardingsphere.shardingproxy.backend.BackendHandlerFactory; import io.shardingsphere.shardingproxy.backend.ResultPacket; import io.shardingsphere.shardingproxy.backend.jdbc.connection.BackendConnection; -import io.shardingsphere.shardingproxy.backend.jdbc.connection.ProxyTransactionManager; +import io.shardingsphere.shardingproxy.backend.jdbc.connection.BackendTransactionManager; import io.shardingsphere.shardingproxy.frontend.common.FrontendHandler; import io.shardingsphere.shardingproxy.runtime.GlobalRegistry; import io.shardingsphere.shardingproxy.transport.common.packet.DatabasePacket; @@ -60,20 +60,20 @@ public final class ComQueryPacket implements QueryCommandPacket { private final BackendHandler backendHandler; - private final ProxyTransactionManager proxyTransactionManager; + private final BackendTransactionManager backendTransactionManager; public ComQueryPacket(final int sequenceId, final int connectionId, final MySQLPacketPayload payload, final BackendConnection backendConnection, final FrontendHandler frontendHandler) { this.sequenceId = sequenceId; sql = payload.readStringEOF(); backendHandler = BackendHandlerFactory.createBackendHandler(connectionId, sequenceId, sql, backendConnection, DatabaseType.MySQL, frontendHandler); - proxyTransactionManager = new ProxyTransactionManager(backendConnection); + backendTransactionManager = new BackendTransactionManager(backendConnection); } public ComQueryPacket(final int sequenceId, final String sql) { this.sequenceId = sequenceId; this.sql = sql; backendHandler = null; - this.proxyTransactionManager = null; + this.backendTransactionManager = null; } @Override @@ -93,7 +93,7 @@ public Optional execute() { if (!operationType.isPresent()) { return Optional.of(backendHandler.execute()); } - proxyTransactionManager.doInTransaction(operationType.get()); + backendTransactionManager.doInTransaction(operationType.get()); return Optional.of(new CommandResponsePackets(new OKPacket(1))); } From 80a87766b4f142b04fe401dc99762176c28eb4da Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Mon, 19 Nov 2018 22:53:59 +0800 Subject: [PATCH 050/113] #1238 Remove transaction operation from BackendConnection. --- .../jdbc/connection/BackendConnection.java | 124 ++---------------- 1 file changed, 9 insertions(+), 115 deletions(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index f8d85475479f7..01d0f195d82b9 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -17,23 +17,16 @@ package io.shardingsphere.shardingproxy.backend.jdbc.connection; -import com.google.common.base.Preconditions; import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import io.shardingsphere.core.constant.ConnectionMode; -import io.shardingsphere.core.constant.transaction.TransactionOperationType; import io.shardingsphere.core.constant.transaction.TransactionType; -import io.shardingsphere.core.event.transaction.ShardingTransactionEvent; -import io.shardingsphere.core.event.transaction.xa.XATransactionEvent; import io.shardingsphere.core.routing.router.masterslave.MasterVisitedManager; import io.shardingsphere.shardingproxy.runtime.GlobalRegistry; import io.shardingsphere.shardingproxy.runtime.schema.LogicSchema; -import io.shardingsphere.spi.transaction.ShardingTransactionHandler; -import io.shardingsphere.spi.transaction.ShardingTransactionHandlerRegistry; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; -import lombok.SneakyThrows; import java.sql.Connection; import java.sql.ResultSet; @@ -72,15 +65,6 @@ public final class BackendConnection implements AutoCloseable { @Setter private TransactionType transactionType = GlobalRegistry.getInstance().getTransactionType(); - /** - * Get connection size. - * - * @return connection size - */ - public int getConnectionSize() { - return cachedConnections.values().size(); - } - /** * Get connections of current thread datasource. * @@ -126,6 +110,15 @@ private List createNewConnections(final ConnectionMode connectionMod return result; } + /** + * Get connection size. + * + * @return connection size + */ + public int getConnectionSize() { + return cachedConnections.values().size(); + } + /** * Add statement. * @@ -170,76 +163,6 @@ public void close() throws SQLException { throwSQLExceptionIfNecessary(exceptions); } - /** - * set auto commit. - * - * @param autoCommit auto commit - */ - private void setAutoCommit(final boolean autoCommit) { - if (!autoCommit) { - status = ConnectionStatus.TRANSACTION; - } - cachedConnections.clear(); - recordMethodInvocation(Connection.class, "setAutoCommit", new Class[]{boolean.class}, new Object[]{autoCommit}); - } - - /** - * Execute transaction by operation type. - * - * @param operationType operation type - * @throws SQLException SQL exception - */ - public void doInTransactional(final TransactionOperationType operationType) throws SQLException { - ShardingTransactionHandler shardingTransactionHandler = ShardingTransactionHandlerRegistry.getInstance().getHandler(transactionType); - if (null != transactionType && transactionType != TransactionType.LOCAL) { - Preconditions.checkNotNull(shardingTransactionHandler, String.format("Cannot find transaction manager of [%s]", transactionType)); - } - if (TransactionType.LOCAL == transactionType) { - switch (operationType) { - case BEGIN: - setAutoCommit(false); - break; - case COMMIT: - commit(); - break; - case ROLLBACK: - rollback(); - break; - default: - } - } else if (TransactionType.XA == transactionType) { - shardingTransactionHandler.doInTransaction(new XATransactionEvent(operationType)); - } - } - - /** - * Do commit. - * - * @throws SQLException SQL exception - */ - private void commit() throws SQLException { - if (ConnectionStatus.TRANSACTION == status) { - Collection exceptions = new LinkedList<>(); - exceptions.addAll(commitConnections()); - throwSQLExceptionIfNecessary(exceptions); - status = ConnectionStatus.TERMINATED; - } - } - - /** - * Do rollback. - * - * @throws SQLException SQL exception - */ - private void rollback() throws SQLException { - if (ConnectionStatus.TRANSACTION == status) { - Collection exceptions = new LinkedList<>(); - exceptions.addAll(rollbackConnections()); - throwSQLExceptionIfNecessary(exceptions); - status = ConnectionStatus.TERMINATED; - } - } - private Collection closeResultSets() { Collection result = new LinkedList<>(); for (ResultSet each : cachedResultSets) { @@ -278,30 +201,6 @@ private Collection closeConnections() { return result; } - private Collection commitConnections() { - Collection result = new LinkedList<>(); - for (Connection each : cachedConnections.values()) { - try { - each.commit(); - } catch (SQLException ex) { - result.add(ex); - } - } - return result; - } - - private Collection rollbackConnections() { - Collection result = new LinkedList<>(); - for (Connection each : cachedConnections.values()) { - try { - each.rollback(); - } catch (SQLException ex) { - result.add(ex); - } - } - return result; - } - private void throwSQLExceptionIfNecessary(final Collection exceptions) throws SQLException { if (exceptions.isEmpty()) { return; @@ -313,11 +212,6 @@ private void throwSQLExceptionIfNecessary(final Collection excepti throw ex; } - @SneakyThrows - private void recordMethodInvocation(final Class targetClass, final String methodName, final Class[] argumentTypes, final Object[] arguments) { - methodInvocations.add(new MethodInvocation(targetClass.getMethod(methodName, argumentTypes), arguments)); - } - private void replayMethodsInvocation(final Object target) { for (MethodInvocation each : methodInvocations) { each.invoke(target); From 42f4808071fa9fbc2a73b695834a7e63e88c6496 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Mon, 19 Nov 2018 23:05:36 +0800 Subject: [PATCH 051/113] #1238 Add setTransactionType. --- .../backend/jdbc/connection/BackendConnection.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index 01d0f195d82b9..bd2ce0922aba0 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -62,9 +62,19 @@ public final class BackendConnection implements AutoCloseable { @Setter private ConnectionStatus status = ConnectionStatus.INIT; - @Setter private TransactionType transactionType = GlobalRegistry.getInstance().getTransactionType(); + /** + * Change transaction type of current channel. + * + * @param transactionType transaction type + */ + public void setTransactionType(final TransactionType transactionType) { + if (ConnectionStatus.TRANSACTION != status) { + this.transactionType = transactionType; + } + } + /** * Get connections of current thread datasource. * From 2b230eb28f44e393341b8c3007e49f000d39e149 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Mon, 19 Nov 2018 23:10:10 +0800 Subject: [PATCH 052/113] #1238 Add setLogicSchema(). --- .../backend/jdbc/connection/BackendConnection.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index bd2ce0922aba0..72745a1c31c70 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -48,7 +48,6 @@ @Getter public final class BackendConnection implements AutoCloseable { - @Setter private LogicSchema logicSchema; private final Multimap cachedConnections = HashMultimap.create(); @@ -75,6 +74,17 @@ public void setTransactionType(final TransactionType transactionType) { } } + /** + * Change logic schema of current channel. + * + * @param logicSchema logic schema + */ + public void setLogicSchema(final LogicSchema logicSchema) { + if (ConnectionStatus.TRANSACTION != status) { + this.logicSchema = logicSchema; + } + } + /** * Get connections of current thread datasource. * From 4af53cae62be696b776731a3949fe26ade949b06 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Mon, 19 Nov 2018 23:31:28 +0800 Subject: [PATCH 053/113] #1238 Add init BackendTransactionManager(). --- .../BackendTransactionManagerTest.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java new file mode 100644 index 0000000000000..358b0e4e1742a --- /dev/null +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java @@ -0,0 +1,21 @@ +/* + * Copyright 2016-2018 shardingsphere.io. + *

+ * Licensed 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 io.shardingsphere.shardingproxy.backend.jdbc.connection; + +public class BackendTransactionManagerTest { +} From 6716b8814d99f90bfc3d0151f0e2bef2c3453eb9 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Mon, 19 Nov 2018 23:44:42 +0800 Subject: [PATCH 054/113] #1238 Refactor BackendTransactionManager. --- .../connection/BackendTransactionManager.java | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManager.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManager.java index 056f4c4a0b09a..dc6245bc4fe02 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManager.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManager.java @@ -55,23 +55,27 @@ public void doInTransaction(final TransactionOperationType operationType) throws Preconditions.checkNotNull(shardingTransactionHandler, String.format("Cannot find transaction manager of [%s]", transactionType)); } if (TransactionType.LOCAL == transactionType) { - switch (operationType) { - case BEGIN: - setAutoCommit(false); - break; - case COMMIT: - commit(); - break; - case ROLLBACK: - rollback(); - break; - default: - } + doLocalTransaction(operationType); } else if (TransactionType.XA == transactionType) { shardingTransactionHandler.doInTransaction(new XATransactionEvent(operationType)); } } + private void doLocalTransaction(final TransactionOperationType operationType) throws SQLException { + switch (operationType) { + case BEGIN: + setAutoCommit(false); + break; + case COMMIT: + commit(); + break; + case ROLLBACK: + rollback(); + break; + default: + } + } + private void setAutoCommit(final boolean autoCommit) { if (!autoCommit) { connection.setStatus(ConnectionStatus.TRANSACTION); From 4c61f45e6b7f419d945f6ffc2f549d830f9f3177 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 01:42:37 +0800 Subject: [PATCH 055/113] #1238 Refactor update transaction status while beginning. --- .../jdbc/connection/BackendTransactionManager.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManager.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManager.java index dc6245bc4fe02..f604e6110ef9c 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManager.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManager.java @@ -54,6 +54,10 @@ public void doInTransaction(final TransactionOperationType operationType) throws if (null != transactionType && transactionType != TransactionType.LOCAL) { Preconditions.checkNotNull(shardingTransactionHandler, String.format("Cannot find transaction manager of [%s]", transactionType)); } + if (TransactionOperationType.BEGIN == operationType && ConnectionStatus.TRANSACTION != connection.getStatus()) { + connection.setStatus(ConnectionStatus.TRANSACTION); + connection.getCachedConnections().clear(); + } if (TransactionType.LOCAL == transactionType) { doLocalTransaction(operationType); } else if (TransactionType.XA == transactionType) { @@ -64,7 +68,7 @@ public void doInTransaction(final TransactionOperationType operationType) throws private void doLocalTransaction(final TransactionOperationType operationType) throws SQLException { switch (operationType) { case BEGIN: - setAutoCommit(false); + setAutoCommit(); break; case COMMIT: commit(); @@ -76,12 +80,8 @@ private void doLocalTransaction(final TransactionOperationType operationType) th } } - private void setAutoCommit(final boolean autoCommit) { - if (!autoCommit) { - connection.setStatus(ConnectionStatus.TRANSACTION); - } - connection.getCachedConnections().clear(); - recordMethodInvocation(Connection.class, "setAutoCommit", new Class[]{boolean.class}, new Object[]{autoCommit}); + private void setAutoCommit() { + recordMethodInvocation(Connection.class, "setAutoCommit", new Class[]{boolean.class}, new Object[]{false}); } private void commit() throws SQLException { From d60018eadd8450bb1da279a09a6cc1f1fde42867 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 01:52:25 +0800 Subject: [PATCH 056/113] #1238 Using backendConnection status to handle isUnsupportedXA(). --- .../shardingproxy/backend/jdbc/JDBCBackendHandler.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/JDBCBackendHandler.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/JDBCBackendHandler.java index f03b9701f2d08..97165ba80a1f3 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/JDBCBackendHandler.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/JDBCBackendHandler.java @@ -33,6 +33,8 @@ import io.shardingsphere.shardingproxy.backend.AbstractBackendHandler; import io.shardingsphere.shardingproxy.backend.BackendExecutorContext; import io.shardingsphere.shardingproxy.backend.ResultPacket; +import io.shardingsphere.shardingproxy.backend.jdbc.connection.BackendConnection; +import io.shardingsphere.shardingproxy.backend.jdbc.connection.ConnectionStatus; import io.shardingsphere.shardingproxy.backend.jdbc.execute.JDBCExecuteEngine; import io.shardingsphere.shardingproxy.backend.jdbc.execute.response.ExecuteQueryResponse; import io.shardingsphere.shardingproxy.backend.jdbc.execute.response.ExecuteResponse; @@ -49,10 +51,8 @@ import io.shardingsphere.shardingproxy.transport.mysql.packet.generic.EofPacket; import io.shardingsphere.shardingproxy.transport.mysql.packet.generic.ErrPacket; import io.shardingsphere.shardingproxy.transport.mysql.packet.generic.OKPacket; -import io.shardingsphere.transaction.xa.manager.XATransactionManagerSPILoader; import lombok.RequiredArgsConstructor; -import javax.transaction.Status; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; @@ -110,8 +110,8 @@ private CommandResponsePackets execute(final SQLRouteResult routeResult) throws } private boolean isUnsupportedXA(final SQLType sqlType) { - return TransactionType.XA == GlobalRegistry.getInstance().getTransactionType() && SQLType.DDL == sqlType - && Status.STATUS_NO_TRANSACTION != XATransactionManagerSPILoader.getInstance().getTransactionManager().getStatus(); + BackendConnection connection = executeEngine.getBackendConnection(); + return TransactionType.XA == connection.getTransactionType() && SQLType.DDL == sqlType && ConnectionStatus.TRANSACTION == connection.getStatus(); } private CommandResponsePackets merge(final SQLStatement sqlStatement) throws SQLException { From 9e4bf096f1c8a476b82f4818bfe7505bb4c9bad6 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 02:05:33 +0800 Subject: [PATCH 057/113] #1238 Add assert connection status within BackendConnectionTest. --- .../backend/jdbc/connection/BackendConnectionTest.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java index e2d49762d7572..fc26785eedee6 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java @@ -68,6 +68,7 @@ public void assertGetConnectionCacheIsEmpty() throws SQLException { List actualConnections = backendConnection.getConnections(ConnectionMode.MEMORY_STRICTLY, "ds1", 2); assertThat(actualConnections.size(), is(2)); assertThat(backendConnection.getConnectionSize(), is(2)); + assertThat(backendConnection.getStatus(), is(ConnectionStatus.RUNNING)); } @Test @@ -76,6 +77,7 @@ public void assertGetConnectionSizeLessThanCache() throws SQLException { List actualConnections = backendConnection.getConnections(ConnectionMode.MEMORY_STRICTLY, "ds1", 2); assertThat(actualConnections.size(), is(2)); assertThat(backendConnection.getConnectionSize(), is(10)); + assertThat(backendConnection.getStatus(), is(ConnectionStatus.RUNNING)); } @Test @@ -85,6 +87,7 @@ public void assertGetConnectionSizeGreaterThanCache() throws SQLException { List actualConnections = backendConnection.getConnections(ConnectionMode.MEMORY_STRICTLY, "ds1", 12); assertThat(actualConnections.size(), is(12)); assertThat(backendConnection.getConnectionSize(), is(12)); + assertThat(backendConnection.getStatus(), is(ConnectionStatus.RUNNING)); } @Test @@ -115,6 +118,7 @@ private void assertOneThreadResult() { List actualConnections = backendConnection.getConnections(ConnectionMode.MEMORY_STRICTLY, "ds1", 12); assertThat(actualConnections.size(), is(12)); assertThat(backendConnection.getConnectionSize(), is(12)); + assertThat(backendConnection.getStatus(), is(ConnectionStatus.RUNNING)); } private List mockNewConnections(final int connectionSize) { From 105804c4cc53a281be4b5237383e0f197afa8ec0 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 02:20:27 +0800 Subject: [PATCH 058/113] #1238 Passing transactionType while new BackendConnection. --- .../jdbc/connection/BackendConnection.java | 9 +++++---- .../frontend/common/FrontendHandler.java | 3 ++- .../connection/BackendConnectionTest.java | 3 ++- .../query/text/query/ComQueryPacketTest.java | 20 +++++-------------- 4 files changed, 14 insertions(+), 21 deletions(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index 72745a1c31c70..939e4c5e81e38 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -22,10 +22,8 @@ import io.shardingsphere.core.constant.ConnectionMode; import io.shardingsphere.core.constant.transaction.TransactionType; import io.shardingsphere.core.routing.router.masterslave.MasterVisitedManager; -import io.shardingsphere.shardingproxy.runtime.GlobalRegistry; import io.shardingsphere.shardingproxy.runtime.schema.LogicSchema; import lombok.Getter; -import lombok.NoArgsConstructor; import lombok.Setter; import java.sql.Connection; @@ -44,7 +42,6 @@ * @author zhaojun * @author zhangliang */ -@NoArgsConstructor @Getter public final class BackendConnection implements AutoCloseable { @@ -61,7 +58,11 @@ public final class BackendConnection implements AutoCloseable { @Setter private ConnectionStatus status = ConnectionStatus.INIT; - private TransactionType transactionType = GlobalRegistry.getInstance().getTransactionType(); + private TransactionType transactionType; + + public BackendConnection(final TransactionType transactionType) { + this.transactionType = transactionType; + } /** * Change transaction type of current channel. diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/frontend/common/FrontendHandler.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/frontend/common/FrontendHandler.java index f378e5f1d715a..105d7b3597dfc 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/frontend/common/FrontendHandler.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/frontend/common/FrontendHandler.java @@ -22,6 +22,7 @@ import io.netty.channel.ChannelInboundHandlerAdapter; import io.shardingsphere.shardingproxy.backend.jdbc.connection.BackendConnection; import io.shardingsphere.shardingproxy.frontend.common.executor.ChannelThreadExecutorGroup; +import io.shardingsphere.shardingproxy.runtime.GlobalRegistry; import lombok.Getter; import lombok.Setter; @@ -35,7 +36,7 @@ public abstract class FrontendHandler extends ChannelInboundHandlerAdapter { private volatile boolean authorized; @Getter - private volatile BackendConnection backendConnection = new BackendConnection(); + private volatile BackendConnection backendConnection = new BackendConnection(GlobalRegistry.getInstance().getTransactionType()); @Getter @Setter diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java index fc26785eedee6..a6b05433c5d51 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java @@ -20,6 +20,7 @@ import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import io.shardingsphere.core.constant.ConnectionMode; +import io.shardingsphere.core.constant.transaction.TransactionType; import io.shardingsphere.shardingproxy.backend.jdbc.datasource.JDBCBackendDataSource; import io.shardingsphere.shardingproxy.runtime.schema.LogicSchema; import lombok.SneakyThrows; @@ -52,7 +53,7 @@ public class BackendConnectionTest { @Mock private JDBCBackendDataSource backendDataSource; - private BackendConnection backendConnection = new BackendConnection(); + private BackendConnection backendConnection = new BackendConnection(TransactionType.LOCAL); @Before @SuppressWarnings("unchecked") diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacketTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacketTest.java index f0f2ef3dcd6ea..8b56c096e0d6e 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacketTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacketTest.java @@ -20,7 +20,6 @@ import com.google.common.base.Optional; import io.shardingsphere.core.constant.ShardingConstant; import io.shardingsphere.core.constant.properties.ShardingProperties; -import io.shardingsphere.core.constant.properties.ShardingPropertiesConstant; import io.shardingsphere.core.constant.transaction.TransactionType; import io.shardingsphere.core.event.transaction.ShardingTransactionEvent; import io.shardingsphere.shardingproxy.backend.BackendHandler; @@ -71,14 +70,14 @@ public final class ComQueryPacketTest { @Mock private MySQLPacketPayload payload; - private BackendConnection backendConnection = new BackendConnection(); + private BackendConnection backendConnection = new BackendConnection(TransactionType.LOCAL); @Mock private FrontendHandler frontendHandler; @BeforeClass public static void init() { - setTransactionType(TransactionType.LOCAL); + setGlobalRegistry(); ShardingTransactionHandlerRegistry.load(); } @@ -90,7 +89,6 @@ public void setUp() { @After public void tearDown() { - setTransactionType(null); FixedXAShardingTransactionHandler.getInvokes().clear(); } @@ -109,16 +107,10 @@ private void setFrontendHandlerSchema() { } @SneakyThrows - private static void setTransactionType(final TransactionType transactionType) { + private static void setGlobalRegistry() { Field field = GlobalRegistry.getInstance().getClass().getDeclaredField("shardingProperties"); field.setAccessible(true); - field.set(GlobalRegistry.getInstance(), getShardingProperties(transactionType)); - } - - private static ShardingProperties getShardingProperties(final TransactionType transactionType) { - Properties props = new Properties(); - props.setProperty(ShardingPropertiesConstant.PROXY_TRANSACTION_ENABLED.getKey(), String.valueOf(transactionType == TransactionType.XA)); - return new ShardingProperties(props); + field.set(GlobalRegistry.getInstance(), new ShardingProperties(new Properties())); } @Test @@ -132,7 +124,6 @@ public void assertWrite() { @Test public void assertExecuteWithoutTransaction() throws SQLException { - setTransactionType(TransactionType.LOCAL); when(payload.readStringEOF()).thenReturn("SELECT id FROM tbl"); BackendHandler backendHandler = mock(BackendHandler.class); when(backendHandler.next()).thenReturn(true, false); @@ -162,8 +153,7 @@ private void setBackendHandler(final ComQueryPacket packet, final BackendHandler @Test public void assertExecuteTCLWithLocalTransaction() { - setTransactionType(TransactionType.LOCAL); - setConnectionStatus(ConnectionStatus.TRANSACTION); + backendConnection.setStatus(ConnectionStatus.TRANSACTION); when(payload.readStringEOF()).thenReturn("COMMIT"); ComQueryPacket packet = new ComQueryPacket(1, 1000, payload, backendConnection, frontendHandler); Optional actual = packet.execute(); From ff86c33250b6c2d68e15561e1a6a9aad2ecaf5fc Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 02:21:58 +0800 Subject: [PATCH 059/113] #1238 Remove setConnectionStatus method from ComQueryPacketTest --- .../command/query/text/query/ComQueryPacketTest.java | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacketTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacketTest.java index 8b56c096e0d6e..a0b0c0dc5bde1 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacketTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/transport/mysql/packet/command/query/text/query/ComQueryPacketTest.java @@ -164,7 +164,7 @@ public void assertExecuteTCLWithLocalTransaction() { @Test public void assertExecuteTCLWithXATransaction() { backendConnection.setTransactionType(TransactionType.XA); - setConnectionStatus(ConnectionStatus.TRANSACTION); + backendConnection.setStatus(ConnectionStatus.TRANSACTION); when(payload.readStringEOF()).thenReturn("ROLLBACK"); ComQueryPacket packet = new ComQueryPacket(1, 1000, payload, backendConnection, frontendHandler); Optional actual = packet.execute(); @@ -176,7 +176,7 @@ public void assertExecuteTCLWithXATransaction() { @Test public void assertExecuteRollbackWithXATransaction() { backendConnection.setTransactionType(TransactionType.XA); - setConnectionStatus(ConnectionStatus.TRANSACTION); + backendConnection.setStatus(ConnectionStatus.TRANSACTION); when(payload.readStringEOF()).thenReturn("COMMIT"); ComQueryPacket packet = new ComQueryPacket(1, 1000, payload, backendConnection, frontendHandler); Optional actual = packet.execute(); @@ -185,13 +185,6 @@ public void assertExecuteRollbackWithXATransaction() { assertThat(FixedXAShardingTransactionHandler.getInvokes().get("commit"), instanceOf(ShardingTransactionEvent.class)); } - @SneakyThrows - private void setConnectionStatus(final ConnectionStatus status) { - Field field = backendConnection.getClass().getDeclaredField("status"); - field.setAccessible(true); - field.set(backendConnection, status); - } - private void assertOKPacket(final CommandResponsePackets actual) { assertThat(actual.getPackets().size(), is(1)); assertThat((actual.getPackets().iterator().next()).getSequenceId(), is(1)); From bce67f534ed714c1b9132aceb81981d7e031a564 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 02:26:36 +0800 Subject: [PATCH 060/113] #1238 Remove null statement of channelInactive. --- .../shardingproxy/frontend/common/FrontendHandler.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/frontend/common/FrontendHandler.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/frontend/common/FrontendHandler.java index 105d7b3597dfc..9acdb502cc7b6 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/frontend/common/FrontendHandler.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/frontend/common/FrontendHandler.java @@ -67,10 +67,7 @@ public final void channelRead(final ChannelHandlerContext context, final Object @Override public final void channelInactive(final ChannelHandlerContext context) { context.fireChannelInactive(); - // TODO :yonglun investigate why null here - if (null != backendConnection) { - backendConnection.cancel(); - } + backendConnection.cancel(); ChannelThreadExecutorGroup.getInstance().unregister(context.channel().id()); } } From 3214833f7cda90c3c52228e7a5c83de49d54c43f Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 02:43:56 +0800 Subject: [PATCH 061/113] #1238 Revise setCachedConnection --- .../backend/jdbc/connection/BackendConnectionTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java index a6b05433c5d51..84457015d8927 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java @@ -74,7 +74,7 @@ public void assertGetConnectionCacheIsEmpty() throws SQLException { @Test public void assertGetConnectionSizeLessThanCache() throws SQLException { - setCachedConnections("ds1", 10); + setCachedConnections(backendConnection, "ds1", 10); List actualConnections = backendConnection.getConnections(ConnectionMode.MEMORY_STRICTLY, "ds1", 2); assertThat(actualConnections.size(), is(2)); assertThat(backendConnection.getConnectionSize(), is(10)); @@ -83,7 +83,7 @@ public void assertGetConnectionSizeLessThanCache() throws SQLException { @Test public void assertGetConnectionSizeGreaterThanCache() throws SQLException { - setCachedConnections("ds1", 10); + setCachedConnections(backendConnection, "ds1", 10); when(backendDataSource.getConnections((ConnectionMode) any(), anyString(), eq(2))).thenReturn(mockNewConnections(2)); List actualConnections = backendConnection.getConnections(ConnectionMode.MEMORY_STRICTLY, "ds1", 12); assertThat(actualConnections.size(), is(12)); @@ -94,7 +94,7 @@ public void assertGetConnectionSizeGreaterThanCache() throws SQLException { @Test @SneakyThrows public void assertMultiThreadGetConnection() { - setCachedConnections("ds1", 10); + setCachedConnections(backendConnection, "ds1", 10); when(backendDataSource.getConnections((ConnectionMode) any(), anyString(), eq(2))).thenReturn(mockNewConnections(2)); Thread thread1 = new Thread(new Runnable() { @Override @@ -132,7 +132,7 @@ private List mockNewConnections(final int connectionSize) { } @SneakyThrows - private void setCachedConnections(final String dsName, final int connectionSize) { + private void setCachedConnections(final BackendConnection backendConnection, final String dsName, final int connectionSize) { Multimap cachedConnections = HashMultimap.create(); cachedConnections.putAll(dsName, mockNewConnections(connectionSize)); Field field = backendConnection.getClass().getDeclaredField("cachedConnections"); From a32b1bcbe2048fe05e3eecca78457fdb17b54730 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 02:45:20 +0800 Subject: [PATCH 062/113] #1238 Add BackendConnectionTest.assertAutoCloseConnection() --- .../connection/BackendConnectionTest.java | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java index 84457015d8927..1afb29bbd79bc 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java @@ -38,6 +38,7 @@ import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; @@ -122,13 +123,18 @@ private void assertOneThreadResult() { assertThat(backendConnection.getStatus(), is(ConnectionStatus.RUNNING)); } - private List mockNewConnections(final int connectionSize) { - List result = new ArrayList<>(); - for (int i = 0; i < connectionSize; i++) { - Connection connection = mock(Connection.class); - result.add(connection); + @Test + public void assertAutoCloseConnection() throws SQLException { + BackendConnection actual; + try (BackendConnection backendConnection = new BackendConnection(TransactionType.LOCAL)) { + backendConnection.setLogicSchema(logicSchema); + setCachedConnections(backendConnection, "ds1", 10); + when(backendDataSource.getConnections((ConnectionMode) any(), anyString(), eq(2))).thenReturn(mockNewConnections(2)); + backendConnection.getConnections(ConnectionMode.MEMORY_STRICTLY, "ds1", 12); + actual = backendConnection; } - return result; + assertThat(actual.getConnectionSize(), is(0)); + assertTrue(actual.getCachedConnections().isEmpty()); } @SneakyThrows @@ -139,4 +145,13 @@ private void setCachedConnections(final BackendConnection backendConnection, fin field.setAccessible(true); field.set(backendConnection, cachedConnections); } + + private List mockNewConnections(final int connectionSize) { + List result = new ArrayList<>(); + for (int i = 0; i < connectionSize; i++) { + Connection connection = mock(Connection.class); + result.add(connection); + } + return result; + } } From 31755d3e93ec3be34b67ebfdf004953dcc411e55 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 02:53:00 +0800 Subject: [PATCH 063/113] #1238 assert close statement and result while connection closed. --- .../backend/jdbc/connection/BackendConnectionTest.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java index 1afb29bbd79bc..f74a120c8e8e2 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java @@ -32,7 +32,9 @@ import java.lang.reflect.Field; import java.sql.Connection; +import java.sql.ResultSet; import java.sql.SQLException; +import java.sql.Statement; import java.util.ArrayList; import java.util.List; @@ -126,15 +128,22 @@ private void assertOneThreadResult() { @Test public void assertAutoCloseConnection() throws SQLException { BackendConnection actual; + ResultSet resultSet = mock(ResultSet.class); + Statement statement = mock(Statement.class); try (BackendConnection backendConnection = new BackendConnection(TransactionType.LOCAL)) { backendConnection.setLogicSchema(logicSchema); setCachedConnections(backendConnection, "ds1", 10); when(backendDataSource.getConnections((ConnectionMode) any(), anyString(), eq(2))).thenReturn(mockNewConnections(2)); backendConnection.getConnections(ConnectionMode.MEMORY_STRICTLY, "ds1", 12); + backendConnection.setStatus(ConnectionStatus.TERMINATED); + backendConnection.add(resultSet); + backendConnection.add(statement); actual = backendConnection; } assertThat(actual.getConnectionSize(), is(0)); assertTrue(actual.getCachedConnections().isEmpty()); + assertTrue(actual.getCachedResultSets().isEmpty()); + assertTrue(actual.getCachedStatements().isEmpty()); } @SneakyThrows From 56bb14027c7f567b94db1dd2ec5bdd1c7c4c30ef Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 03:07:56 +0800 Subject: [PATCH 064/113] #1238 Add setMockResultSetAndStatement. --- .../connection/BackendConnectionTest.java | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java index f74a120c8e8e2..de67195e46adb 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java @@ -38,12 +38,14 @@ import java.util.ArrayList; import java.util.List; +import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -126,26 +128,35 @@ private void assertOneThreadResult() { } @Test - public void assertAutoCloseConnection() throws SQLException { - BackendConnection actual; - ResultSet resultSet = mock(ResultSet.class); - Statement statement = mock(Statement.class); + public void assertAutoCloseConnection() { + BackendConnection actual = null; try (BackendConnection backendConnection = new BackendConnection(TransactionType.LOCAL)) { backendConnection.setLogicSchema(logicSchema); setCachedConnections(backendConnection, "ds1", 10); when(backendDataSource.getConnections((ConnectionMode) any(), anyString(), eq(2))).thenReturn(mockNewConnections(2)); backendConnection.getConnections(ConnectionMode.MEMORY_STRICTLY, "ds1", 12); backendConnection.setStatus(ConnectionStatus.TERMINATED); - backendConnection.add(resultSet); - backendConnection.add(statement); + setMockResultSetAndStatement(backendConnection); actual = backendConnection; + } catch (SQLException ex) { + assertThat(ex.getNextException().getNextException(), instanceOf(SQLException.class)); } + assert actual != null; assertThat(actual.getConnectionSize(), is(0)); assertTrue(actual.getCachedConnections().isEmpty()); assertTrue(actual.getCachedResultSets().isEmpty()); assertTrue(actual.getCachedStatements().isEmpty()); } + private void setMockResultSetAndStatement(final BackendConnection backendConnection) throws SQLException { + ResultSet resultSet = mock(ResultSet.class); + Statement statement = mock(Statement.class); + doThrow(SQLException.class).when(resultSet).close(); + doThrow(SQLException.class).when(statement).close(); + backendConnection.add(resultSet); + backendConnection.add(statement); + } + @SneakyThrows private void setCachedConnections(final BackendConnection backendConnection, final String dsName, final int connectionSize) { Multimap cachedConnections = HashMultimap.create(); From 0f799a3a32a27c78e7942790760c11c3ddad30f6 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 03:18:14 +0800 Subject: [PATCH 065/113] #1238 Add assertFailedSwitchTransactionTypeWhileBegin. --- .../jdbc/connection/BackendConnectionTest.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java index de67195e46adb..32b0f6fe4dc27 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java @@ -20,6 +20,7 @@ import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import io.shardingsphere.core.constant.ConnectionMode; +import io.shardingsphere.core.constant.transaction.TransactionOperationType; import io.shardingsphere.core.constant.transaction.TransactionType; import io.shardingsphere.shardingproxy.backend.jdbc.datasource.JDBCBackendDataSource; import io.shardingsphere.shardingproxy.runtime.schema.LogicSchema; @@ -40,6 +41,7 @@ import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertSame; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; @@ -132,6 +134,7 @@ public void assertAutoCloseConnection() { BackendConnection actual = null; try (BackendConnection backendConnection = new BackendConnection(TransactionType.LOCAL)) { backendConnection.setLogicSchema(logicSchema); + backendConnection.setTransactionType(TransactionType.XA); setCachedConnections(backendConnection, "ds1", 10); when(backendDataSource.getConnections((ConnectionMode) any(), anyString(), eq(2))).thenReturn(mockNewConnections(2)); backendConnection.getConnections(ConnectionMode.MEMORY_STRICTLY, "ds1", 12); @@ -148,6 +151,14 @@ public void assertAutoCloseConnection() { assertTrue(actual.getCachedStatements().isEmpty()); } + @Test + public void assertFailedSwitchTransactionTypeWhileBegin() throws SQLException { + BackendTransactionManager transactionManager = new BackendTransactionManager(backendConnection); + transactionManager.doInTransaction(TransactionOperationType.BEGIN); + backendConnection.setTransactionType(TransactionType.XA); + assertSame(TransactionType.LOCAL, backendConnection.getTransactionType()); + } + private void setMockResultSetAndStatement(final BackendConnection backendConnection) throws SQLException { ResultSet resultSet = mock(ResultSet.class); Statement statement = mock(Statement.class); From 09ed6a9f51e8e8374366aab9a2faea395d3c01ab Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 03:20:04 +0800 Subject: [PATCH 066/113] #1238 Add assertFailedSwitchLogicSchemaWhileBegin. --- .../backend/jdbc/connection/BackendConnectionTest.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java index 32b0f6fe4dc27..2d794e368a55c 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java @@ -159,6 +159,14 @@ public void assertFailedSwitchTransactionTypeWhileBegin() throws SQLException { assertSame(TransactionType.LOCAL, backendConnection.getTransactionType()); } + @Test + public void assertFailedSwitchLogicSchemaWhileBegin() throws SQLException { + BackendTransactionManager transactionManager = new BackendTransactionManager(backendConnection); + transactionManager.doInTransaction(TransactionOperationType.BEGIN); + backendConnection.setLogicSchema(mock(LogicSchema.class)); + assertSame(logicSchema, backendConnection.getLogicSchema()); + } + private void setMockResultSetAndStatement(final BackendConnection backendConnection) throws SQLException { ResultSet resultSet = mock(ResultSet.class); Statement statement = mock(Statement.class); From acefe085b9b7de75b7e1afa0b9f31a3960961c3d Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 03:31:49 +0800 Subject: [PATCH 067/113] #1238 Refactor BackendConnection.cancel(). --- .../backend/jdbc/connection/BackendConnection.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index 939e4c5e81e38..0ecc7b978e534 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -25,6 +25,7 @@ import io.shardingsphere.shardingproxy.runtime.schema.LogicSchema; import lombok.Getter; import lombok.Setter; +import lombok.extern.slf4j.Slf4j; import java.sql.Connection; import java.sql.ResultSet; @@ -42,6 +43,7 @@ * @author zhaojun * @author zhangliang */ +@Slf4j @Getter public final class BackendConnection implements AutoCloseable { @@ -162,12 +164,17 @@ public void add(final ResultSet resultSet) { * Cancel statement. */ public void cancel() { + Collection exceptions = new LinkedList<>(); for (Statement each : cachedStatements) { try { each.cancel(); - } catch (final SQLException ignored) { + } catch (final SQLException ex) { + exceptions.add(ex); } } + if (!exceptions.isEmpty()) { + log.warn("Failed cancel statement", exceptions); + } } @Override From 992381ed7e703bc0b64c68c63e21e72569fe392f Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 03:37:56 +0800 Subject: [PATCH 068/113] #1238 clear statement After cancel. --- .../backend/jdbc/connection/BackendConnection.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index 0ecc7b978e534..a708b6a5afdc4 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -173,8 +173,9 @@ public void cancel() { } } if (!exceptions.isEmpty()) { - log.warn("Failed cancel statement", exceptions); + log.warn("Failed to cancel statement due to {}", exceptions); } + cachedStatements.clear(); } @Override From 5990f1fde7bec94076f8d3bab1b1f7054665764a Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 03:38:19 +0800 Subject: [PATCH 069/113] #1238 Add BackendConnectionTest.assertCancelStatement(). --- .../connection/BackendConnectionTest.java | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java index 2d794e368a55c..5b89399d954bc 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java @@ -139,7 +139,7 @@ public void assertAutoCloseConnection() { when(backendDataSource.getConnections((ConnectionMode) any(), anyString(), eq(2))).thenReturn(mockNewConnections(2)); backendConnection.getConnections(ConnectionMode.MEMORY_STRICTLY, "ds1", 12); backendConnection.setStatus(ConnectionStatus.TERMINATED); - setMockResultSetAndStatement(backendConnection); + mockResultSetAndStatement(backendConnection); actual = backendConnection; } catch (SQLException ex) { assertThat(ex.getNextException().getNextException(), instanceOf(SQLException.class)); @@ -151,6 +151,15 @@ public void assertAutoCloseConnection() { assertTrue(actual.getCachedStatements().isEmpty()); } + private void mockResultSetAndStatement(final BackendConnection backendConnection) throws SQLException { + ResultSet resultSet = mock(ResultSet.class); + Statement statement = mock(Statement.class); + doThrow(SQLException.class).when(resultSet).close(); + doThrow(SQLException.class).when(statement).close(); + backendConnection.add(resultSet); + backendConnection.add(statement); + } + @Test public void assertFailedSwitchTransactionTypeWhileBegin() throws SQLException { BackendTransactionManager transactionManager = new BackendTransactionManager(backendConnection); @@ -167,12 +176,16 @@ public void assertFailedSwitchLogicSchemaWhileBegin() throws SQLException { assertSame(logicSchema, backendConnection.getLogicSchema()); } - private void setMockResultSetAndStatement(final BackendConnection backendConnection) throws SQLException { - ResultSet resultSet = mock(ResultSet.class); + @Test + public void assertCancelStatement() throws SQLException { + mockStatementCancel(backendConnection); + backendConnection.cancel(); + assertTrue(backendConnection.getCachedStatements().isEmpty()); + } + + private void mockStatementCancel(final BackendConnection backendConnection) throws SQLException { Statement statement = mock(Statement.class); - doThrow(SQLException.class).when(resultSet).close(); - doThrow(SQLException.class).when(statement).close(); - backendConnection.add(resultSet); + doThrow(SQLException.class).when(statement).cancel(); backendConnection.add(statement); } From 4346a7197ddf5f6efc9ce65682498d57bc575765 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 15:50:47 +0800 Subject: [PATCH 070/113] #1238 Add init BackendTransactionManagerTest case frame. --- .../BackendTransactionManagerTest.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java index 358b0e4e1742a..0594dff14e56f 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java @@ -17,5 +17,27 @@ package io.shardingsphere.shardingproxy.backend.jdbc.connection; +import org.junit.Test; + public class BackendTransactionManagerTest { + + @Test + public void assertLocalTransactionCommit() { + + } + + @Test + public void assertLocalTransactionRollback() { + + } + + @Test + public void assertXATransactionCommit() { + + } + + @Test + public void assertXATransactionRollback() { + + } } From 267f4083e2ab4f2c94f71f432b2c0ae9e0900210 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 16:05:05 +0800 Subject: [PATCH 071/113] #1238 Implement assertLocalTransactionCommit. --- .../BackendTransactionManagerTest.java | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java index 0594dff14e56f..56e92bc3cbce0 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java @@ -17,13 +17,41 @@ package io.shardingsphere.shardingproxy.backend.jdbc.connection; +import io.shardingsphere.core.constant.transaction.TransactionOperationType; +import io.shardingsphere.core.constant.transaction.TransactionType; import org.junit.Test; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.mock; + public class BackendTransactionManagerTest { + private BackendConnection backendConnection = new BackendConnection(TransactionType.LOCAL); + + private BackendTransactionManager backendTransactionManager = new BackendTransactionManager(backendConnection); + @Test - public void assertLocalTransactionCommit() { + public void assertLocalTransactionCommit() throws SQLException { + backendTransactionManager.doInTransaction(TransactionOperationType.BEGIN); + assertThat(backendConnection.getStatus(), is(ConnectionStatus.TRANSACTION)); + assertThat(backendConnection.getMethodInvocations().size(), is(1)); + assertThat(backendConnection.getMethodInvocations().iterator().next().getArguments(), is(new Object[]{false})); + backendTransactionManager.doInTransaction(TransactionOperationType.COMMIT); + } + private List mockNewConnections(final int connectionSize) { + List result = new ArrayList<>(); + for (int i = 0; i < connectionSize; i++) { + Connection connection = mock(Connection.class); + result.add(connection); + } + return result; } @Test From e9e8c929417aad99fe02b44538ca3fdbb44c15e8 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 16:09:53 +0800 Subject: [PATCH 072/113] #1238 Add MockConnectionUtil --- .../jdbc/connection/MockConnectionUtil.java | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/MockConnectionUtil.java diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/MockConnectionUtil.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/MockConnectionUtil.java new file mode 100644 index 0000000000000..4c21ba8c277a9 --- /dev/null +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/MockConnectionUtil.java @@ -0,0 +1,62 @@ +/* + * Copyright 2016-2018 shardingsphere.io. + *

+ * Licensed 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 io.shardingsphere.shardingproxy.backend.jdbc.connection; + +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; +import lombok.SneakyThrows; + +import java.lang.reflect.Field; +import java.sql.Connection; +import java.util.ArrayList; +import java.util.List; + +import static org.mockito.Mockito.mock; + +/** + * Mock backend connection Util. + * + * @author zhaojun + */ +public class MockConnectionUtil { + + /** + * Mock set cached connections. + * + * @param backendConnection backend connection + * @param dsName datasource name + * @param connectionSize connection size + */ + @SneakyThrows + public static void setCachedConnections(final BackendConnection backendConnection, final String dsName, final int connectionSize) { + Multimap cachedConnections = HashMultimap.create(); + cachedConnections.putAll(dsName, mockNewConnections(connectionSize)); + Field field = backendConnection.getClass().getDeclaredField("cachedConnections"); + field.setAccessible(true); + field.set(backendConnection, cachedConnections); + } + + private static List mockNewConnections(final int connectionSize) { + List result = new ArrayList<>(); + for (int i = 0; i < connectionSize; i++) { + Connection connection = mock(Connection.class); + result.add(connection); + } + return result; + } +} From f856a868a219b4175e06631421f57a05b25e7945 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 16:13:22 +0800 Subject: [PATCH 073/113] #1238 for checkstyle. --- .../backend/jdbc/connection/MockConnectionUtil.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/MockConnectionUtil.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/MockConnectionUtil.java index 4c21ba8c277a9..d3cd555d16a10 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/MockConnectionUtil.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/MockConnectionUtil.java @@ -33,7 +33,7 @@ * * @author zhaojun */ -public class MockConnectionUtil { +class MockConnectionUtil { /** * Mock set cached connections. @@ -43,7 +43,7 @@ public class MockConnectionUtil { * @param connectionSize connection size */ @SneakyThrows - public static void setCachedConnections(final BackendConnection backendConnection, final String dsName, final int connectionSize) { + static void setCachedConnections(final BackendConnection backendConnection, final String dsName, final int connectionSize) { Multimap cachedConnections = HashMultimap.create(); cachedConnections.putAll(dsName, mockNewConnections(connectionSize)); Field field = backendConnection.getClass().getDeclaredField("cachedConnections"); @@ -51,7 +51,13 @@ public static void setCachedConnections(final BackendConnection backendConnectio field.set(backendConnection, cachedConnections); } - private static List mockNewConnections(final int connectionSize) { + /** + * Mock new connections. + * + * @param connectionSize connection size + * @return list of connection + */ + static List mockNewConnections(final int connectionSize) { List result = new ArrayList<>(); for (int i = 0; i < connectionSize; i++) { Connection connection = mock(Connection.class); From 1f812011f86a6aa63e9ad805ab698a8b49de7d94 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 16:14:12 +0800 Subject: [PATCH 074/113] #1238 Refactor BackendConnectionTest using MockConnectionUtil. --- .../connection/BackendConnectionTest.java | 38 ++++--------------- 1 file changed, 8 insertions(+), 30 deletions(-) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java index 5b89399d954bc..88e970bec4bff 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java @@ -17,8 +17,6 @@ package io.shardingsphere.shardingproxy.backend.jdbc.connection; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.Multimap; import io.shardingsphere.core.constant.ConnectionMode; import io.shardingsphere.core.constant.transaction.TransactionOperationType; import io.shardingsphere.core.constant.transaction.TransactionType; @@ -31,12 +29,10 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; -import java.lang.reflect.Field; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; -import java.util.ArrayList; import java.util.List; import static org.hamcrest.CoreMatchers.instanceOf; @@ -72,7 +68,7 @@ public void setup() { @Test public void assertGetConnectionCacheIsEmpty() throws SQLException { - when(backendDataSource.getConnections((ConnectionMode) any(), anyString(), eq(2))).thenReturn(mockNewConnections(2)); + when(backendDataSource.getConnections((ConnectionMode) any(), anyString(), eq(2))).thenReturn(MockConnectionUtil.mockNewConnections(2)); List actualConnections = backendConnection.getConnections(ConnectionMode.MEMORY_STRICTLY, "ds1", 2); assertThat(actualConnections.size(), is(2)); assertThat(backendConnection.getConnectionSize(), is(2)); @@ -81,7 +77,7 @@ public void assertGetConnectionCacheIsEmpty() throws SQLException { @Test public void assertGetConnectionSizeLessThanCache() throws SQLException { - setCachedConnections(backendConnection, "ds1", 10); + MockConnectionUtil.setCachedConnections(backendConnection, "ds1", 10); List actualConnections = backendConnection.getConnections(ConnectionMode.MEMORY_STRICTLY, "ds1", 2); assertThat(actualConnections.size(), is(2)); assertThat(backendConnection.getConnectionSize(), is(10)); @@ -90,8 +86,8 @@ public void assertGetConnectionSizeLessThanCache() throws SQLException { @Test public void assertGetConnectionSizeGreaterThanCache() throws SQLException { - setCachedConnections(backendConnection, "ds1", 10); - when(backendDataSource.getConnections((ConnectionMode) any(), anyString(), eq(2))).thenReturn(mockNewConnections(2)); + MockConnectionUtil.setCachedConnections(backendConnection, "ds1", 10); + when(backendDataSource.getConnections((ConnectionMode) any(), anyString(), eq(2))).thenReturn(MockConnectionUtil.mockNewConnections(2)); List actualConnections = backendConnection.getConnections(ConnectionMode.MEMORY_STRICTLY, "ds1", 12); assertThat(actualConnections.size(), is(12)); assertThat(backendConnection.getConnectionSize(), is(12)); @@ -101,8 +97,8 @@ public void assertGetConnectionSizeGreaterThanCache() throws SQLException { @Test @SneakyThrows public void assertMultiThreadGetConnection() { - setCachedConnections(backendConnection, "ds1", 10); - when(backendDataSource.getConnections((ConnectionMode) any(), anyString(), eq(2))).thenReturn(mockNewConnections(2)); + MockConnectionUtil.setCachedConnections(backendConnection, "ds1", 10); + when(backendDataSource.getConnections((ConnectionMode) any(), anyString(), eq(2))).thenReturn(MockConnectionUtil.mockNewConnections(2)); Thread thread1 = new Thread(new Runnable() { @Override public void run() { @@ -135,8 +131,8 @@ public void assertAutoCloseConnection() { try (BackendConnection backendConnection = new BackendConnection(TransactionType.LOCAL)) { backendConnection.setLogicSchema(logicSchema); backendConnection.setTransactionType(TransactionType.XA); - setCachedConnections(backendConnection, "ds1", 10); - when(backendDataSource.getConnections((ConnectionMode) any(), anyString(), eq(2))).thenReturn(mockNewConnections(2)); + MockConnectionUtil.setCachedConnections(backendConnection, "ds1", 10); + when(backendDataSource.getConnections((ConnectionMode) any(), anyString(), eq(2))).thenReturn(MockConnectionUtil.mockNewConnections(2)); backendConnection.getConnections(ConnectionMode.MEMORY_STRICTLY, "ds1", 12); backendConnection.setStatus(ConnectionStatus.TERMINATED); mockResultSetAndStatement(backendConnection); @@ -188,22 +184,4 @@ private void mockStatementCancel(final BackendConnection backendConnection) thro doThrow(SQLException.class).when(statement).cancel(); backendConnection.add(statement); } - - @SneakyThrows - private void setCachedConnections(final BackendConnection backendConnection, final String dsName, final int connectionSize) { - Multimap cachedConnections = HashMultimap.create(); - cachedConnections.putAll(dsName, mockNewConnections(connectionSize)); - Field field = backendConnection.getClass().getDeclaredField("cachedConnections"); - field.setAccessible(true); - field.set(backendConnection, cachedConnections); - } - - private List mockNewConnections(final int connectionSize) { - List result = new ArrayList<>(); - for (int i = 0; i < connectionSize; i++) { - Connection connection = mock(Connection.class); - result.add(connection); - } - return result; - } } From e6c04eb97bf977f38bd8eeb4091bd21e3f229092 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 16:29:21 +0800 Subject: [PATCH 075/113] #1238 Revise BackendTransactionManagerTest.assertLocalTransactionCommit --- .../BackendTransactionManagerTest.java | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java index 56e92bc3cbce0..b0346a34ce512 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java @@ -23,12 +23,12 @@ import java.sql.Connection; import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; +import java.util.Iterator; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; -import static org.mockito.Mockito.mock; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.verify; public class BackendTransactionManagerTest { @@ -38,20 +38,18 @@ public class BackendTransactionManagerTest { @Test public void assertLocalTransactionCommit() throws SQLException { + MockConnectionUtil.setCachedConnections(backendConnection, "ds1", 2); backendTransactionManager.doInTransaction(TransactionOperationType.BEGIN); assertThat(backendConnection.getStatus(), is(ConnectionStatus.TRANSACTION)); assertThat(backendConnection.getMethodInvocations().size(), is(1)); assertThat(backendConnection.getMethodInvocations().iterator().next().getArguments(), is(new Object[]{false})); + assertTrue(backendConnection.getCachedConnections().isEmpty()); + MockConnectionUtil.setCachedConnections(backendConnection, "ds1", 2); backendTransactionManager.doInTransaction(TransactionOperationType.COMMIT); - } - - private List mockNewConnections(final int connectionSize) { - List result = new ArrayList<>(); - for (int i = 0; i < connectionSize; i++) { - Connection connection = mock(Connection.class); - result.add(connection); - } - return result; + Iterator iterator = backendConnection.getCachedConnections().values().iterator(); + verify(iterator.next()).commit(); + verify(iterator.next()).commit(); + assertThat(backendConnection.getStatus(), is(ConnectionStatus.TERMINATED)); } @Test From 97000fabaf1638b47371161706f4d789fd28c76f Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 16:31:11 +0800 Subject: [PATCH 076/113] #1238 Add BackendTransactionManagerTest.assertLocalTransactionRollback --- .../jdbc/connection/BackendTransactionManagerTest.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java index b0346a34ce512..b3adb84b62818 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java @@ -53,8 +53,14 @@ public void assertLocalTransactionCommit() throws SQLException { } @Test - public void assertLocalTransactionRollback() { - + public void assertLocalTransactionRollback() throws SQLException { + backendTransactionManager.doInTransaction(TransactionOperationType.BEGIN); + MockConnectionUtil.setCachedConnections(backendConnection, "ds1", 2); + backendTransactionManager.doInTransaction(TransactionOperationType.ROLLBACK); + Iterator iterator = backendConnection.getCachedConnections().values().iterator(); + verify(iterator.next()).rollback(); + verify(iterator.next()).rollback(); + assertThat(backendConnection.getStatus(), is(ConnectionStatus.TERMINATED)); } @Test From 48f7a04f0194ca9899cbabed322f5de065fe0be9 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 16:42:30 +0800 Subject: [PATCH 077/113] #1238 Add BackendTransactionManagerTest.assertXATransactionCommit --- .../jdbc/connection/BackendTransactionManagerTest.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java index b3adb84b62818..1e1f201e417ba 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java @@ -64,8 +64,13 @@ public void assertLocalTransactionRollback() throws SQLException { } @Test - public void assertXATransactionCommit() { - + public void assertXATransactionCommit() throws SQLException { + backendConnection.setTransactionType(TransactionType.XA); + backendTransactionManager.doInTransaction(TransactionOperationType.BEGIN); + assertTrue(backendConnection.getMethodInvocations().isEmpty()); + assertThat(backendConnection.getStatus(), is(ConnectionStatus.TRANSACTION)); + backendTransactionManager.doInTransaction(TransactionOperationType.COMMIT); + assertThat(backendConnection.getStatus(), is(ConnectionStatus.TERMINATED)); } @Test From 2b9edf1f5d21dbbff6017ac2e8b6c514a7029c93 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 16:44:05 +0800 Subject: [PATCH 078/113] #1238 Add beforeClass --- .../jdbc/connection/BackendTransactionManagerTest.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java index 1e1f201e417ba..18a285312d442 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java @@ -19,6 +19,8 @@ import io.shardingsphere.core.constant.transaction.TransactionOperationType; import io.shardingsphere.core.constant.transaction.TransactionType; +import io.shardingsphere.spi.transaction.ShardingTransactionHandlerRegistry; +import org.junit.BeforeClass; import org.junit.Test; import java.sql.Connection; @@ -36,6 +38,11 @@ public class BackendTransactionManagerTest { private BackendTransactionManager backendTransactionManager = new BackendTransactionManager(backendConnection); + @BeforeClass + public static void beforeClass() { + ShardingTransactionHandlerRegistry.load(); + } + @Test public void assertLocalTransactionCommit() throws SQLException { MockConnectionUtil.setCachedConnections(backendConnection, "ds1", 2); From 47563fbe7cc382b68392ac05eeec23c1806bd7db Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 16:45:11 +0800 Subject: [PATCH 079/113] #1238 Modify Connection status after executed XA transaction. --- .../backend/jdbc/connection/BackendTransactionManager.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManager.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManager.java index f604e6110ef9c..e45075f8a0cac 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManager.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManager.java @@ -62,6 +62,9 @@ public void doInTransaction(final TransactionOperationType operationType) throws doLocalTransaction(operationType); } else if (TransactionType.XA == transactionType) { shardingTransactionHandler.doInTransaction(new XATransactionEvent(operationType)); + if (TransactionOperationType.BEGIN != operationType) { + connection.setStatus(ConnectionStatus.TERMINATED); + } } } From 28991680e548e3471addb32cf9473398a7f1f9b0 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 16:46:29 +0800 Subject: [PATCH 080/113] #1238 Add assertXATransactionRollback. --- .../jdbc/connection/BackendTransactionManagerTest.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java index 18a285312d442..f47e4b7d6c054 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java @@ -81,7 +81,12 @@ public void assertXATransactionCommit() throws SQLException { } @Test - public void assertXATransactionRollback() { - + public void assertXATransactionRollback() throws SQLException { + backendConnection.setTransactionType(TransactionType.XA); + backendTransactionManager.doInTransaction(TransactionOperationType.BEGIN); + assertTrue(backendConnection.getMethodInvocations().isEmpty()); + assertThat(backendConnection.getStatus(), is(ConnectionStatus.TRANSACTION)); + backendTransactionManager.doInTransaction(TransactionOperationType.ROLLBACK); + assertThat(backendConnection.getStatus(), is(ConnectionStatus.TERMINATED)); } } From 6eb0f3d6c25d0a57f8d2d2b85b5a5214271c54de Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 17:19:25 +0800 Subject: [PATCH 081/113] #1238 mock throw exception while doing transaction. --- .../backend/jdbc/connection/MockConnectionUtil.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/MockConnectionUtil.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/MockConnectionUtil.java index d3cd555d16a10..4f6758682ba29 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/MockConnectionUtil.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/MockConnectionUtil.java @@ -23,9 +23,11 @@ import java.lang.reflect.Field; import java.sql.Connection; +import java.sql.SQLException; import java.util.ArrayList; import java.util.List; +import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; /** @@ -57,10 +59,13 @@ static void setCachedConnections(final BackendConnection backendConnection, fina * @param connectionSize connection size * @return list of connection */ - static List mockNewConnections(final int connectionSize) { + static List mockNewConnections(final int connectionSize) throws SQLException { List result = new ArrayList<>(); for (int i = 0; i < connectionSize; i++) { Connection connection = mock(Connection.class); + doThrow(SQLException.class).when(connection).rollback(); + doThrow(SQLException.class).when(connection).commit(); + doThrow(SQLException.class).when(connection).close(); result.add(connection); } return result; From d60ee24dba0206d761f7757079cf17d56341b52f Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 17:19:51 +0800 Subject: [PATCH 082/113] #1238 fix test error. --- .../connection/BackendTransactionManagerTest.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java index f47e4b7d6c054..df66fb1bfc808 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java @@ -52,7 +52,11 @@ public void assertLocalTransactionCommit() throws SQLException { assertThat(backendConnection.getMethodInvocations().iterator().next().getArguments(), is(new Object[]{false})); assertTrue(backendConnection.getCachedConnections().isEmpty()); MockConnectionUtil.setCachedConnections(backendConnection, "ds1", 2); - backendTransactionManager.doInTransaction(TransactionOperationType.COMMIT); + try { + backendTransactionManager.doInTransaction(TransactionOperationType.COMMIT); + } catch (SQLException ex) { + // ignore + } Iterator iterator = backendConnection.getCachedConnections().values().iterator(); verify(iterator.next()).commit(); verify(iterator.next()).commit(); @@ -63,7 +67,11 @@ public void assertLocalTransactionCommit() throws SQLException { public void assertLocalTransactionRollback() throws SQLException { backendTransactionManager.doInTransaction(TransactionOperationType.BEGIN); MockConnectionUtil.setCachedConnections(backendConnection, "ds1", 2); - backendTransactionManager.doInTransaction(TransactionOperationType.ROLLBACK); + try { + backendTransactionManager.doInTransaction(TransactionOperationType.ROLLBACK); + } catch (SQLException ex) { + // ignore + } Iterator iterator = backendConnection.getCachedConnections().values().iterator(); verify(iterator.next()).rollback(); verify(iterator.next()).rollback(); From aa36a1051f63605be4a4617ad64b9ff4d76bab09 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 17:20:31 +0800 Subject: [PATCH 083/113] #1238 change connection status before throw exception. --- .../backend/jdbc/connection/BackendTransactionManager.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManager.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManager.java index e45075f8a0cac..2d90fd2fcdd07 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManager.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManager.java @@ -91,8 +91,8 @@ private void commit() throws SQLException { if (ConnectionStatus.TRANSACTION == connection.getStatus()) { Collection exceptions = new LinkedList<>(); exceptions.addAll(commitConnections()); - throwSQLExceptionIfNecessary(exceptions); connection.setStatus(ConnectionStatus.TERMINATED); + throwSQLExceptionIfNecessary(exceptions); } } @@ -100,8 +100,8 @@ private void rollback() throws SQLException { if (ConnectionStatus.TRANSACTION == connection.getStatus()) { Collection exceptions = new LinkedList<>(); exceptions.addAll(rollbackConnections()); - throwSQLExceptionIfNecessary(exceptions); connection.setStatus(ConnectionStatus.TERMINATED); + throwSQLExceptionIfNecessary(exceptions); } } From bb4a12f9884cdc2451b51ea68f4f2072f0b3c568 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 17:46:37 +0800 Subject: [PATCH 084/113] #1238 Add mockThrowException --- .../jdbc/connection/MockConnectionUtil.java | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/MockConnectionUtil.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/MockConnectionUtil.java index 4f6758682ba29..a5a899357d241 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/MockConnectionUtil.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/MockConnectionUtil.java @@ -25,6 +25,7 @@ import java.sql.Connection; import java.sql.SQLException; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import static org.mockito.Mockito.doThrow; @@ -62,12 +63,21 @@ static void setCachedConnections(final BackendConnection backendConnection, fina static List mockNewConnections(final int connectionSize) throws SQLException { List result = new ArrayList<>(); for (int i = 0; i < connectionSize; i++) { - Connection connection = mock(Connection.class); - doThrow(SQLException.class).when(connection).rollback(); - doThrow(SQLException.class).when(connection).commit(); - doThrow(SQLException.class).when(connection).close(); - result.add(connection); + result.add(mock(Connection.class)); } return result; } + + static void mockThrowException(final Collection connections) { + try { + for (Connection each : connections) { + doThrow(SQLException.class).when(each).commit(); + doThrow(SQLException.class).when(each).rollback(); + doThrow(SQLException.class).when(each).close(); + } + + } catch (Exception ex) { + // ignore + } + } } From f23a69c42b83570c8067f2fe8f93811c24c6237f Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 17:49:16 +0800 Subject: [PATCH 085/113] #1238 for checkstyle. --- .../jdbc/connection/MockConnectionUtil.java | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/MockConnectionUtil.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/MockConnectionUtil.java index a5a899357d241..de0e056ad106a 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/MockConnectionUtil.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/MockConnectionUtil.java @@ -60,7 +60,7 @@ static void setCachedConnections(final BackendConnection backendConnection, fina * @param connectionSize connection size * @return list of connection */ - static List mockNewConnections(final int connectionSize) throws SQLException { + static List mockNewConnections(final int connectionSize) { List result = new ArrayList<>(); for (int i = 0; i < connectionSize; i++) { result.add(mock(Connection.class)); @@ -68,16 +68,11 @@ static List mockNewConnections(final int connectionSize) throws SQLE return result; } - static void mockThrowException(final Collection connections) { - try { - for (Connection each : connections) { - doThrow(SQLException.class).when(each).commit(); - doThrow(SQLException.class).when(each).rollback(); - doThrow(SQLException.class).when(each).close(); - } - - } catch (Exception ex) { - // ignore + static void mockThrowException(final Collection connections) throws SQLException { + for (Connection each : connections) { + doThrow(SQLException.class).when(each).commit(); + doThrow(SQLException.class).when(each).rollback(); + doThrow(SQLException.class).when(each).close(); } } } From ecd1b88bffdfb3f1aab410a676e01fd870f71902 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 17:50:10 +0800 Subject: [PATCH 086/113] #1238 Revise BackendTransactionManagerTest --- .../backend/jdbc/connection/BackendTransactionManagerTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java index df66fb1bfc808..acb39e252d72c 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java @@ -52,6 +52,7 @@ public void assertLocalTransactionCommit() throws SQLException { assertThat(backendConnection.getMethodInvocations().iterator().next().getArguments(), is(new Object[]{false})); assertTrue(backendConnection.getCachedConnections().isEmpty()); MockConnectionUtil.setCachedConnections(backendConnection, "ds1", 2); + MockConnectionUtil.mockThrowException(backendConnection.getCachedConnections().values()); try { backendTransactionManager.doInTransaction(TransactionOperationType.COMMIT); } catch (SQLException ex) { @@ -67,6 +68,7 @@ public void assertLocalTransactionCommit() throws SQLException { public void assertLocalTransactionRollback() throws SQLException { backendTransactionManager.doInTransaction(TransactionOperationType.BEGIN); MockConnectionUtil.setCachedConnections(backendConnection, "ds1", 2); + MockConnectionUtil.mockThrowException(backendConnection.getCachedConnections().values()); try { backendTransactionManager.doInTransaction(TransactionOperationType.ROLLBACK); } catch (SQLException ex) { From cc6a384473ffaf07dae7065a1383b3b53a8d3a40 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 17:56:30 +0800 Subject: [PATCH 087/113] #1238 Increase case for coverage. --- .../jdbc/connection/BackendTransactionManagerTest.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java index acb39e252d72c..c3d4f31b21e68 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java @@ -62,6 +62,9 @@ public void assertLocalTransactionCommit() throws SQLException { verify(iterator.next()).commit(); verify(iterator.next()).commit(); assertThat(backendConnection.getStatus(), is(ConnectionStatus.TERMINATED)); + backendTransactionManager.doInTransaction(TransactionOperationType.BEGIN); + MockConnectionUtil.setCachedConnections(backendConnection, "ds1", 2); + backendTransactionManager.doInTransaction(TransactionOperationType.COMMIT); } @Test @@ -78,6 +81,9 @@ public void assertLocalTransactionRollback() throws SQLException { verify(iterator.next()).rollback(); verify(iterator.next()).rollback(); assertThat(backendConnection.getStatus(), is(ConnectionStatus.TERMINATED)); + backendTransactionManager.doInTransaction(TransactionOperationType.BEGIN); + MockConnectionUtil.setCachedConnections(backendConnection, "ds1", 2); + backendTransactionManager.doInTransaction(TransactionOperationType.ROLLBACK); } @Test @@ -88,6 +94,7 @@ public void assertXATransactionCommit() throws SQLException { assertThat(backendConnection.getStatus(), is(ConnectionStatus.TRANSACTION)); backendTransactionManager.doInTransaction(TransactionOperationType.COMMIT); assertThat(backendConnection.getStatus(), is(ConnectionStatus.TERMINATED)); + backendTransactionManager.doInTransaction(TransactionOperationType.BEGIN); } @Test From 01ac95c306dbf3ad6ff36da61a0b7d3212c4fdb5 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 17:58:26 +0800 Subject: [PATCH 088/113] #1238 Add assertLocalTransactionCommitWithException. --- .../connection/BackendTransactionManagerTest.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java index c3d4f31b21e68..2fb08a278a133 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java @@ -67,6 +67,18 @@ public void assertLocalTransactionCommit() throws SQLException { backendTransactionManager.doInTransaction(TransactionOperationType.COMMIT); } + @Test + public void assertLocalTransactionCommitWithException() throws SQLException { + backendTransactionManager.doInTransaction(TransactionOperationType.BEGIN); + MockConnectionUtil.setCachedConnections(backendConnection, "ds1", 2); + MockConnectionUtil.mockThrowException(backendConnection.getCachedConnections().values()); + try { + backendTransactionManager.doInTransaction(TransactionOperationType.COMMIT); + } catch (SQLException ex) { + // ignore + } + } + @Test public void assertLocalTransactionRollback() throws SQLException { backendTransactionManager.doInTransaction(TransactionOperationType.BEGIN); From 0fd0a2f1a957c1d075dd81ed6ee9017736a8be92 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 17:59:04 +0800 Subject: [PATCH 089/113] #1238 Revise assertLocalTransactionCommit. --- .../jdbc/connection/BackendTransactionManagerTest.java | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java index 2fb08a278a133..96efc10d9a9e3 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java @@ -52,19 +52,11 @@ public void assertLocalTransactionCommit() throws SQLException { assertThat(backendConnection.getMethodInvocations().iterator().next().getArguments(), is(new Object[]{false})); assertTrue(backendConnection.getCachedConnections().isEmpty()); MockConnectionUtil.setCachedConnections(backendConnection, "ds1", 2); - MockConnectionUtil.mockThrowException(backendConnection.getCachedConnections().values()); - try { - backendTransactionManager.doInTransaction(TransactionOperationType.COMMIT); - } catch (SQLException ex) { - // ignore - } + backendTransactionManager.doInTransaction(TransactionOperationType.COMMIT); Iterator iterator = backendConnection.getCachedConnections().values().iterator(); verify(iterator.next()).commit(); verify(iterator.next()).commit(); assertThat(backendConnection.getStatus(), is(ConnectionStatus.TERMINATED)); - backendTransactionManager.doInTransaction(TransactionOperationType.BEGIN); - MockConnectionUtil.setCachedConnections(backendConnection, "ds1", 2); - backendTransactionManager.doInTransaction(TransactionOperationType.COMMIT); } @Test From fa19cae39484b5cf4500a5566c8577d7f9588022 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 17:59:51 +0800 Subject: [PATCH 090/113] #1238 Add assertLocalTransactionRollbackWithException. --- .../connection/BackendTransactionManagerTest.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java index 96efc10d9a9e3..b3469937fa9e8 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java @@ -90,6 +90,18 @@ public void assertLocalTransactionRollback() throws SQLException { backendTransactionManager.doInTransaction(TransactionOperationType.ROLLBACK); } + @Test + public void assertLocalTransactionRollbackWithException() throws SQLException { + backendTransactionManager.doInTransaction(TransactionOperationType.BEGIN); + MockConnectionUtil.setCachedConnections(backendConnection, "ds1", 2); + MockConnectionUtil.mockThrowException(backendConnection.getCachedConnections().values()); + try { + backendTransactionManager.doInTransaction(TransactionOperationType.ROLLBACK); + } catch (SQLException ex) { + // ignore + } + } + @Test public void assertXATransactionCommit() throws SQLException { backendConnection.setTransactionType(TransactionType.XA); From 01bc5a965628a3a588ba3242b5b4d4b4733730ef Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 18:00:27 +0800 Subject: [PATCH 091/113] #1238 Revise assertLocalTransactionRollback. --- .../jdbc/connection/BackendTransactionManagerTest.java | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java index b3469937fa9e8..dd51853c1d3b3 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java @@ -75,19 +75,11 @@ public void assertLocalTransactionCommitWithException() throws SQLException { public void assertLocalTransactionRollback() throws SQLException { backendTransactionManager.doInTransaction(TransactionOperationType.BEGIN); MockConnectionUtil.setCachedConnections(backendConnection, "ds1", 2); - MockConnectionUtil.mockThrowException(backendConnection.getCachedConnections().values()); - try { - backendTransactionManager.doInTransaction(TransactionOperationType.ROLLBACK); - } catch (SQLException ex) { - // ignore - } + backendTransactionManager.doInTransaction(TransactionOperationType.ROLLBACK); Iterator iterator = backendConnection.getCachedConnections().values().iterator(); verify(iterator.next()).rollback(); verify(iterator.next()).rollback(); assertThat(backendConnection.getStatus(), is(ConnectionStatus.TERMINATED)); - backendTransactionManager.doInTransaction(TransactionOperationType.BEGIN); - MockConnectionUtil.setCachedConnections(backendConnection, "ds1", 2); - backendTransactionManager.doInTransaction(TransactionOperationType.ROLLBACK); } @Test From f381f218de5d811e5c7b0eaf3e42a626b7ffdd0a Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 18:02:41 +0800 Subject: [PATCH 092/113] #1238 Revise BackendTransactionManagerTest. --- .../jdbc/connection/BackendTransactionManagerTest.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java index dd51853c1d3b3..8aec3202712c9 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManagerTest.java @@ -27,6 +27,7 @@ import java.sql.SQLException; import java.util.Iterator; +import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; @@ -67,8 +68,9 @@ public void assertLocalTransactionCommitWithException() throws SQLException { try { backendTransactionManager.doInTransaction(TransactionOperationType.COMMIT); } catch (SQLException ex) { - // ignore + assertThat(ex.getNextException().getNextException(), instanceOf(SQLException.class)); } + assertThat(backendConnection.getStatus(), is(ConnectionStatus.TERMINATED)); } @Test @@ -90,8 +92,9 @@ public void assertLocalTransactionRollbackWithException() throws SQLException { try { backendTransactionManager.doInTransaction(TransactionOperationType.ROLLBACK); } catch (SQLException ex) { - // ignore + assertThat(ex.getNextException().getNextException(), instanceOf(SQLException.class)); } + assertThat(backendConnection.getStatus(), is(ConnectionStatus.TERMINATED)); } @Test From 9caf75035677e2e448b7c9262d8ea33b551342bc Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 18:18:13 +0800 Subject: [PATCH 093/113] #1238 Add assertGetConnectionWithMethodInvocation. --- .../connection/BackendConnectionTest.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java index 88e970bec4bff..f9659a3a2f7d4 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java @@ -29,10 +29,13 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; +import java.lang.reflect.Field; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; +import java.util.ArrayList; +import java.util.Collection; import java.util.List; import static org.hamcrest.CoreMatchers.instanceOf; @@ -45,6 +48,8 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) @@ -94,6 +99,26 @@ public void assertGetConnectionSizeGreaterThanCache() throws SQLException { assertThat(backendConnection.getStatus(), is(ConnectionStatus.RUNNING)); } + @Test + public void assertGetConnectionWithMethodInvocation() throws SQLException { + when(backendDataSource.getConnections((ConnectionMode) any(), anyString(), eq(2))).thenReturn(MockConnectionUtil.mockNewConnections(2)); + setMethodInvocation(); + List actualConnections = backendConnection.getConnections(ConnectionMode.MEMORY_STRICTLY, "ds1", 2); + verify(backendConnection.getMethodInvocations().iterator().next(), times(2)).invoke(any()); + assertThat(actualConnections.size(), is(2)); + assertThat(backendConnection.getStatus(), is(ConnectionStatus.RUNNING)); + } + + @SneakyThrows + private void setMethodInvocation() { + MethodInvocation invocation = mock(MethodInvocation.class); + Collection methodInvocations = new ArrayList<>(); + methodInvocations.add(invocation); + Field field = backendConnection.getClass().getDeclaredField("methodInvocations"); + field.setAccessible(true); + field.set(backendConnection, methodInvocations); + } + @Test @SneakyThrows public void assertMultiThreadGetConnection() { From 37ba09b9088a4efc53b17f8f3c6a7ffc198de84b Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 18:20:51 +0800 Subject: [PATCH 094/113] #1238 Rename assertAutoCloseConnection => assertAutoCloseConnectionWithException. --- .../backend/jdbc/connection/BackendConnectionTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java index f9659a3a2f7d4..8e7c73f6f99ca 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java @@ -151,7 +151,7 @@ private void assertOneThreadResult() { } @Test - public void assertAutoCloseConnection() { + public void assertAutoCloseConnectionWithException() { BackendConnection actual = null; try (BackendConnection backendConnection = new BackendConnection(TransactionType.LOCAL)) { backendConnection.setLogicSchema(logicSchema); From 4631a2d77cef1f53c3703c089229d824b8459134 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 18:22:53 +0800 Subject: [PATCH 095/113] #1238 Add MockThrowException in assertAutoCloseConnectionWithException --- .../backend/jdbc/connection/BackendConnectionTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java index 8e7c73f6f99ca..c7b5d353044fc 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java @@ -158,6 +158,7 @@ public void assertAutoCloseConnectionWithException() { backendConnection.setTransactionType(TransactionType.XA); MockConnectionUtil.setCachedConnections(backendConnection, "ds1", 10); when(backendDataSource.getConnections((ConnectionMode) any(), anyString(), eq(2))).thenReturn(MockConnectionUtil.mockNewConnections(2)); + MockConnectionUtil.mockThrowException(backendConnection.getCachedConnections().values()); backendConnection.getConnections(ConnectionMode.MEMORY_STRICTLY, "ds1", 12); backendConnection.setStatus(ConnectionStatus.TERMINATED); mockResultSetAndStatement(backendConnection); From fa4c4ebce3a976427fc96113a43cd6f563f49f31 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 18:39:28 +0800 Subject: [PATCH 096/113] #1238 Add BackendConnectionTest.assertAutoCloseConnection --- .../connection/BackendConnectionTest.java | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java index c7b5d353044fc..b05e038c1d81e 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java @@ -150,6 +150,25 @@ private void assertOneThreadResult() { assertThat(backendConnection.getStatus(), is(ConnectionStatus.RUNNING)); } + @Test + public void assertAutoCloseConnection() throws SQLException { + BackendConnection actual; + try (BackendConnection backendConnection = new BackendConnection(TransactionType.LOCAL)) { + backendConnection.setLogicSchema(logicSchema); + backendConnection.setTransactionType(TransactionType.XA); + MockConnectionUtil.setCachedConnections(backendConnection, "ds1", 10); + when(backendDataSource.getConnections((ConnectionMode) any(), anyString(), eq(2))).thenReturn(MockConnectionUtil.mockNewConnections(2)); + backendConnection.getConnections(ConnectionMode.MEMORY_STRICTLY, "ds1", 12); + backendConnection.setStatus(ConnectionStatus.TERMINATED); + mockResultSetAndStatement(backendConnection); + actual = backendConnection; + } + assertThat(actual.getConnectionSize(), is(0)); + assertTrue(actual.getCachedConnections().isEmpty()); + assertTrue(actual.getCachedResultSets().isEmpty()); + assertTrue(actual.getCachedStatements().isEmpty()); + } + @Test public void assertAutoCloseConnectionWithException() { BackendConnection actual = null; @@ -173,7 +192,14 @@ public void assertAutoCloseConnectionWithException() { assertTrue(actual.getCachedStatements().isEmpty()); } - private void mockResultSetAndStatement(final BackendConnection backendConnection) throws SQLException { + private void mockResultSetAndStatement(final BackendConnection backendConnection) { + ResultSet resultSet = mock(ResultSet.class); + Statement statement = mock(Statement.class); + backendConnection.add(resultSet); + backendConnection.add(statement); + } + + private void mockResultSetAndStatementWithException(final BackendConnection backendConnection) throws SQLException { ResultSet resultSet = mock(ResultSet.class); Statement statement = mock(Statement.class); doThrow(SQLException.class).when(resultSet).close(); From e4b238c4284a124106540420146330bf039a17ea Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 18:41:49 +0800 Subject: [PATCH 097/113] #1238 Revise assertAutoCloseConnectionWithException. --- .../backend/jdbc/connection/BackendConnectionTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java index b05e038c1d81e..82632a331e69f 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java @@ -180,7 +180,7 @@ public void assertAutoCloseConnectionWithException() { MockConnectionUtil.mockThrowException(backendConnection.getCachedConnections().values()); backendConnection.getConnections(ConnectionMode.MEMORY_STRICTLY, "ds1", 12); backendConnection.setStatus(ConnectionStatus.TERMINATED); - mockResultSetAndStatement(backendConnection); + mockResultSetAndStatementWithException(backendConnection); actual = backendConnection; } catch (SQLException ex) { assertThat(ex.getNextException().getNextException(), instanceOf(SQLException.class)); From f6c69beb7c3357141e49fcc9be7af1c4ecdd3c11 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 19:00:27 +0800 Subject: [PATCH 098/113] #1238 Revise assertAutoCloseConnectionWithException. --- .../jdbc/connection/BackendConnectionTest.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java index 82632a331e69f..3501e8a1032cc 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnectionTest.java @@ -177,10 +177,10 @@ public void assertAutoCloseConnectionWithException() { backendConnection.setTransactionType(TransactionType.XA); MockConnectionUtil.setCachedConnections(backendConnection, "ds1", 10); when(backendDataSource.getConnections((ConnectionMode) any(), anyString(), eq(2))).thenReturn(MockConnectionUtil.mockNewConnections(2)); - MockConnectionUtil.mockThrowException(backendConnection.getCachedConnections().values()); backendConnection.getConnections(ConnectionMode.MEMORY_STRICTLY, "ds1", 12); backendConnection.setStatus(ConnectionStatus.TERMINATED); - mockResultSetAndStatementWithException(backendConnection); + mockResultSetAndStatement(backendConnection); + mockResultSetAndStatementException(backendConnection); actual = backendConnection; } catch (SQLException ex) { assertThat(ex.getNextException().getNextException(), instanceOf(SQLException.class)); @@ -199,13 +199,13 @@ private void mockResultSetAndStatement(final BackendConnection backendConnection backendConnection.add(statement); } - private void mockResultSetAndStatementWithException(final BackendConnection backendConnection) throws SQLException { - ResultSet resultSet = mock(ResultSet.class); - Statement statement = mock(Statement.class); - doThrow(SQLException.class).when(resultSet).close(); - doThrow(SQLException.class).when(statement).close(); - backendConnection.add(resultSet); - backendConnection.add(statement); + private void mockResultSetAndStatementException(final BackendConnection backendConnection) throws SQLException { + for (Statement each : backendConnection.getCachedStatements()) { + doThrow(SQLException.class).when(each).close(); + } + for (ResultSet each : backendConnection.getCachedResultSets()) { + doThrow(SQLException.class).when(each).close(); + } } @Test From dcb0eae87ea38c89b9d07c3c32a889c71892df47 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 19:04:53 +0800 Subject: [PATCH 099/113] #1238 for checkstyle. --- .../backend/jdbc/connection/MethodInvocation.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/MethodInvocation.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/MethodInvocation.java index 733dd7d521482..2ee346d76067a 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/MethodInvocation.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/MethodInvocation.java @@ -29,7 +29,7 @@ * @author zhaojun */ @RequiredArgsConstructor -public class MethodInvocation { +class MethodInvocation { @Getter private final Method method; @@ -43,7 +43,7 @@ public class MethodInvocation { * @param target target object */ @SneakyThrows - public void invoke(final Object target) { + void invoke(final Object target) { method.invoke(target, arguments); } } From 257621b59e5104be91a69cc4710785cb1918c2b4 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 19:32:57 +0800 Subject: [PATCH 100/113] #1238 Open transaction type config. --- .../shardingsphere/shardingproxy/runtime/GlobalRegistry.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/runtime/GlobalRegistry.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/runtime/GlobalRegistry.java index d666dbad0aaee..2a755c493eabc 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/runtime/GlobalRegistry.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/runtime/GlobalRegistry.java @@ -133,9 +133,8 @@ private LogicSchema getLogicSchema(final String schemaName, final MapgetValue(ShardingPropertiesConstant.PROXY_TRANSACTION_ENABLED) ? TransactionType.XA : TransactionType.LOCAL; + return TransactionType.valueOf((String) shardingProperties.getValue(ShardingPropertiesConstant.PROXY_TRANSACTION_TYPE)); } /** From feec08f7dca1337756fe4c6e73c7ac05ac39b01b Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 19:33:09 +0800 Subject: [PATCH 101/113] #1238 Revise test error. --- .../frontend/common/executor/ExecutorGroupTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/frontend/common/executor/ExecutorGroupTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/frontend/common/executor/ExecutorGroupTest.java index 7454e48cdcf11..b55c279b6d7b0 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/frontend/common/executor/ExecutorGroupTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/frontend/common/executor/ExecutorGroupTest.java @@ -72,7 +72,7 @@ private void setTransactionType(final TransactionType transactionType) throws Re private ShardingProperties getShardingProperties(final TransactionType transactionType) { Properties props = new Properties(); - props.setProperty(ShardingPropertiesConstant.PROXY_TRANSACTION_ENABLED.getKey(), String.valueOf(transactionType == TransactionType.XA)); + props.setProperty(ShardingPropertiesConstant.PROXY_TRANSACTION_TYPE.getKey(), transactionType.name()); return new ShardingProperties(props); } } From 1df5800f7bdbaf2f11f3802497dc1877700f8242 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Tue, 20 Nov 2018 19:34:30 +0800 Subject: [PATCH 102/113] #1238 Revise transaction config in server.yaml --- sharding-proxy/src/main/resources/conf/server.yaml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sharding-proxy/src/main/resources/conf/server.yaml b/sharding-proxy/src/main/resources/conf/server.yaml index 27ec39083e63f..c19de987e55bb 100644 --- a/sharding-proxy/src/main/resources/conf/server.yaml +++ b/sharding-proxy/src/main/resources/conf/server.yaml @@ -19,14 +19,12 @@ # max.connections.size.per.query: 1 # acceptor.size: 16 # The default value is available processors count * 2. # executor.size: 16 # Infinite by default. -# proxy.transaction.enabled: false -# # Be valid when proxy.transaction.enabled is true. # # LOCAL: Proxy will run with LOCAL transaction. # # XA: Proxy will run with XA transaction. # # BASE: Proxy will run with B.A.S.E transaction. -# proxy.transaction.type: BASE +# proxy.transaction.type: LOCAL # proxy.opentracing.enabled: false -# sql.show: true +# sql.show: false # #configMap: # sharding-key1: sharding-value1 From 5cd5b40983b265a8398443ba377279717461c0ad Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Wed, 21 Nov 2018 23:23:48 +0800 Subject: [PATCH 103/113] #1238 Release connection when create a new transaction. --- .../backend/jdbc/connection/BackendConnection.java | 8 ++++---- .../jdbc/connection/BackendTransactionManager.java | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index a708b6a5afdc4..015d722a06b63 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -185,9 +185,7 @@ public void close() throws SQLException { exceptions.addAll(closeStatements()); exceptions.addAll(closeResultSets()); if (ConnectionStatus.TERMINATED == status) { - exceptions.addAll(closeConnections()); - cachedConnections.clear(); - methodInvocations.clear(); + exceptions.addAll(releaseConnections()); } throwSQLExceptionIfNecessary(exceptions); } @@ -218,7 +216,7 @@ private Collection closeStatements() { return result; } - private Collection closeConnections() { + Collection releaseConnections() { Collection result = new LinkedList<>(); for (Connection each : cachedConnections.values()) { try { @@ -227,6 +225,8 @@ private Collection closeConnections() { result.add(ex); } } + cachedConnections.clear(); + methodInvocations.clear(); return result; } diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManager.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManager.java index 2d90fd2fcdd07..857e965def2a9 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManager.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManager.java @@ -56,7 +56,7 @@ public void doInTransaction(final TransactionOperationType operationType) throws } if (TransactionOperationType.BEGIN == operationType && ConnectionStatus.TRANSACTION != connection.getStatus()) { connection.setStatus(ConnectionStatus.TRANSACTION); - connection.getCachedConnections().clear(); + connection.releaseConnections(); } if (TransactionType.LOCAL == transactionType) { doLocalTransaction(operationType); From ae04c00166797129a3c4ef8d6ff0f39ae3f4c6f6 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Thu, 22 Nov 2018 12:23:21 +0800 Subject: [PATCH 104/113] #1238 Force rollback connection while do Close --- .../jdbc/connection/BackendConnection.java | 1 + .../frontend/common/FrontendHandler.java | 3 + .../main/resources/conf/config-sharding.yaml | 94 +++++++++---------- .../src/main/resources/conf/server.yaml | 30 +++--- 4 files changed, 66 insertions(+), 62 deletions(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index 015d722a06b63..03e747868cb90 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -220,6 +220,7 @@ Collection releaseConnections() { Collection result = new LinkedList<>(); for (Connection each : cachedConnections.values()) { try { + each.rollback(); each.close(); } catch (SQLException ex) { result.add(ex); diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/frontend/common/FrontendHandler.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/frontend/common/FrontendHandler.java index 9acdb502cc7b6..d0c2c60095aac 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/frontend/common/FrontendHandler.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/frontend/common/FrontendHandler.java @@ -25,6 +25,7 @@ import io.shardingsphere.shardingproxy.runtime.GlobalRegistry; import lombok.Getter; import lombok.Setter; +import lombok.SneakyThrows; /** * Frontend handler. @@ -65,8 +66,10 @@ public final void channelRead(final ChannelHandlerContext context, final Object protected abstract void executeCommand(ChannelHandlerContext context, ByteBuf message); @Override + @SneakyThrows public final void channelInactive(final ChannelHandlerContext context) { context.fireChannelInactive(); + backendConnection.close(); backendConnection.cancel(); ChannelThreadExecutorGroup.getInstance().unregister(context.channel().id()); } diff --git a/sharding-proxy/src/main/resources/conf/config-sharding.yaml b/sharding-proxy/src/main/resources/conf/config-sharding.yaml index e2daaed0fdf69..987decf682ebd 100644 --- a/sharding-proxy/src/main/resources/conf/config-sharding.yaml +++ b/sharding-proxy/src/main/resources/conf/config-sharding.yaml @@ -8,50 +8,50 @@ # ###################################################################################################### -#schemaName: sharding_db -# -#dataSources: -# ds_0: -# url: jdbc:mysql://127.0.0.1:3306/demo_ds_0?serverTimezone=UTC&useSSL=false -# username: root -# password: -# autoCommit: true -# connectionTimeout: 30000 -# idleTimeout: 60000 -# maxLifetime: 1800000 -# maximumPoolSize: 50 -# ds_1: -# url: jdbc:mysql://127.0.0.1:3306/demo_ds_1?serverTimezone=UTC&useSSL=false -# username: root -# password: -# autoCommit: true -# connectionTimeout: 30000 -# idleTimeout: 60000 -# maxLifetime: 1800000 -# maximumPoolSize: 50 -# -#shardingRule: -# tables: -# t_order: -# actualDataNodes: ds_${0..1}.t_order_${0..1} -# tableStrategy: -# inline: -# shardingColumn: order_id -# algorithmExpression: t_order_${order_id % 2} -# keyGeneratorColumnName: order_id -# t_order_item: -# actualDataNodes: ds_${0..1}.t_order_item_${0..1} -# tableStrategy: -# inline: -# shardingColumn: order_id -# algorithmExpression: t_order_item_${order_id % 2} -# keyGeneratorColumnName: order_item_id -# bindingTables: -# - t_order,t_order_item -# defaultDatabaseStrategy: -# inline: -# shardingColumn: user_id -# algorithmExpression: ds_${user_id % 2} -# defaultTableStrategy: -# none: -# defaultKeyGeneratorClassName: io.shardingsphere.core.keygen.DefaultKeyGenerator +schemaName: sharding_db + +dataSources: + ds_0: + url: jdbc:mysql://127.0.0.1:3306/demo_ds_0?serverTimezone=UTC&useSSL=false + username: root + password: + autoCommit: true + connectionTimeout: 30000 + idleTimeout: 60000 + maxLifetime: 1800000 + maximumPoolSize: 50 + ds_1: + url: jdbc:mysql://127.0.0.1:3306/demo_ds_1?serverTimezone=UTC&useSSL=false + username: root + password: + autoCommit: true + connectionTimeout: 30000 + idleTimeout: 60000 + maxLifetime: 1800000 + maximumPoolSize: 50 + +shardingRule: + tables: + t_order: + actualDataNodes: ds_${0..1}.t_order_${0..1} + tableStrategy: + inline: + shardingColumn: order_id + algorithmExpression: t_order_${order_id % 2} + keyGeneratorColumnName: order_id + t_order_item: + actualDataNodes: ds_${0..1}.t_order_item_${0..1} + tableStrategy: + inline: + shardingColumn: order_id + algorithmExpression: t_order_item_${order_id % 2} + keyGeneratorColumnName: order_item_id + bindingTables: + - t_order,t_order_item + defaultDatabaseStrategy: + inline: + shardingColumn: user_id + algorithmExpression: ds_${user_id % 2} + defaultTableStrategy: + none: + defaultKeyGeneratorClassName: io.shardingsphere.core.keygen.DefaultKeyGenerator diff --git a/sharding-proxy/src/main/resources/conf/server.yaml b/sharding-proxy/src/main/resources/conf/server.yaml index c19de987e55bb..d5405020b7e9b 100644 --- a/sharding-proxy/src/main/resources/conf/server.yaml +++ b/sharding-proxy/src/main/resources/conf/server.yaml @@ -11,21 +11,21 @@ # serverLists: localhost:2181 # namespace: orchestration # -#authentication: -# username: root -# password: root -# -#props: -# max.connections.size.per.query: 1 -# acceptor.size: 16 # The default value is available processors count * 2. -# executor.size: 16 # Infinite by default. -# # LOCAL: Proxy will run with LOCAL transaction. -# # XA: Proxy will run with XA transaction. -# # BASE: Proxy will run with B.A.S.E transaction. -# proxy.transaction.type: LOCAL -# proxy.opentracing.enabled: false -# sql.show: false -# +authentication: + username: root + password: root + +props: + max.connections.size.per.query: 8 + acceptor.size: 16 # The default value is available processors count * 2. + executor.size: 16 # Infinite by default. + # LOCAL: Proxy will run with LOCAL transaction. + # XA: Proxy will run with XA transaction. + # BASE: Proxy will run with B.A.S.E transaction. + proxy.transaction.type: LOCAL + proxy.opentracing.enabled: false + sql.show: false + #configMap: # sharding-key1: sharding-value1 # sharding-key2: sharding-value2 From 07eb666a15c0dd35a6d302c12757bf706f32d5af Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Thu, 22 Nov 2018 12:41:00 +0800 Subject: [PATCH 105/113] #1238 Add foreClose flag --- .../backend/jdbc/connection/BackendConnection.java | 6 +++++- .../shardingproxy/frontend/common/FrontendHandler.java | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index 03e747868cb90..e921cbc08d928 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -180,11 +180,15 @@ public void cancel() { @Override public void close() throws SQLException { + close(false); + } + + public void close(final boolean forceClose) throws SQLException { Collection exceptions = new LinkedList<>(); MasterVisitedManager.clear(); exceptions.addAll(closeStatements()); exceptions.addAll(closeResultSets()); - if (ConnectionStatus.TERMINATED == status) { + if (ConnectionStatus.TERMINATED == status || forceClose) { exceptions.addAll(releaseConnections()); } throwSQLExceptionIfNecessary(exceptions); diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/frontend/common/FrontendHandler.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/frontend/common/FrontendHandler.java index d0c2c60095aac..c02aeba458291 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/frontend/common/FrontendHandler.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/frontend/common/FrontendHandler.java @@ -69,7 +69,7 @@ public final void channelRead(final ChannelHandlerContext context, final Object @SneakyThrows public final void channelInactive(final ChannelHandlerContext context) { context.fireChannelInactive(); - backendConnection.close(); + backendConnection.close(true); backendConnection.cancel(); ChannelThreadExecutorGroup.getInstance().unregister(context.channel().id()); } From 61a043506a4791d765ac359cc298818e39d293ba Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Thu, 22 Nov 2018 12:44:38 +0800 Subject: [PATCH 106/113] #1238 Add forceRollback flag. --- .../backend/jdbc/connection/BackendConnection.java | 8 +++++--- .../jdbc/connection/BackendTransactionManager.java | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index e921cbc08d928..8fa9183877b34 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -189,7 +189,7 @@ public void close(final boolean forceClose) throws SQLException { exceptions.addAll(closeStatements()); exceptions.addAll(closeResultSets()); if (ConnectionStatus.TERMINATED == status || forceClose) { - exceptions.addAll(releaseConnections()); + exceptions.addAll(releaseConnections(forceClose)); } throwSQLExceptionIfNecessary(exceptions); } @@ -220,11 +220,13 @@ private Collection closeStatements() { return result; } - Collection releaseConnections() { + Collection releaseConnections(final boolean forceRollback) { Collection result = new LinkedList<>(); for (Connection each : cachedConnections.values()) { try { - each.rollback(); + if (forceRollback) { + each.rollback(); + } each.close(); } catch (SQLException ex) { result.add(ex); diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManager.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManager.java index 857e965def2a9..e69b6905c7eff 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManager.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendTransactionManager.java @@ -56,7 +56,7 @@ public void doInTransaction(final TransactionOperationType operationType) throws } if (TransactionOperationType.BEGIN == operationType && ConnectionStatus.TRANSACTION != connection.getStatus()) { connection.setStatus(ConnectionStatus.TRANSACTION); - connection.releaseConnections(); + connection.releaseConnections(false); } if (TransactionType.LOCAL == transactionType) { doLocalTransaction(operationType); From a04199a73d9e6112f4b1f9f6250f95e9a55b5487 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Thu, 22 Nov 2018 12:50:06 +0800 Subject: [PATCH 107/113] #1238 Revise releaseConnections. --- .../backend/jdbc/connection/BackendConnection.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index 8fa9183877b34..0728a9212d5ba 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -224,7 +224,7 @@ Collection releaseConnections(final boolean forceRollback) { Collection result = new LinkedList<>(); for (Connection each : cachedConnections.values()) { try { - if (forceRollback) { + if (forceRollback && ConnectionStatus.TRANSACTION == status) { each.rollback(); } each.close(); From b387355422c5e37ad0d0256ef73bc2ba716bb5e7 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Thu, 22 Nov 2018 12:51:44 +0800 Subject: [PATCH 108/113] #1238 for checkstyle. --- .../backend/jdbc/connection/BackendConnection.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index 0728a9212d5ba..af8a619bac399 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -183,6 +183,12 @@ public void close() throws SQLException { close(false); } + /** + * Close cached connection. + * + * @param forceClose force close flag + * @throws SQLException SQL exception + */ public void close(final boolean forceClose) throws SQLException { Collection exceptions = new LinkedList<>(); MasterVisitedManager.clear(); From f4f3ba644b1876aafe18b4de024c75647fe6969b Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Thu, 22 Nov 2018 18:41:25 +0800 Subject: [PATCH 109/113] #1238 Make cachedConnections ascend order. --- .../backend/jdbc/connection/BackendConnection.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java index af8a619bac399..1e5065c1e94bd 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/jdbc/connection/BackendConnection.java @@ -17,7 +17,7 @@ package io.shardingsphere.shardingproxy.backend.jdbc.connection; -import com.google.common.collect.HashMultimap; +import com.google.common.collect.LinkedHashMultimap; import com.google.common.collect.Multimap; import io.shardingsphere.core.constant.ConnectionMode; import io.shardingsphere.core.constant.transaction.TransactionType; @@ -49,7 +49,7 @@ public final class BackendConnection implements AutoCloseable { private LogicSchema logicSchema; - private final Multimap cachedConnections = HashMultimap.create(); + private final Multimap cachedConnections = LinkedHashMultimap.create(); private final Collection cachedStatements = new CopyOnWriteArrayList<>(); From 068e2dd5d21cc74466aef245e2b8a4e44468004d Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Thu, 22 Nov 2018 18:43:33 +0800 Subject: [PATCH 110/113] #1238 Revert config file. --- .../main/resources/conf/config-sharding.yaml | 94 +++++++++---------- .../src/main/resources/conf/server.yaml | 30 +++--- 2 files changed, 62 insertions(+), 62 deletions(-) diff --git a/sharding-proxy/src/main/resources/conf/config-sharding.yaml b/sharding-proxy/src/main/resources/conf/config-sharding.yaml index 987decf682ebd..e2daaed0fdf69 100644 --- a/sharding-proxy/src/main/resources/conf/config-sharding.yaml +++ b/sharding-proxy/src/main/resources/conf/config-sharding.yaml @@ -8,50 +8,50 @@ # ###################################################################################################### -schemaName: sharding_db - -dataSources: - ds_0: - url: jdbc:mysql://127.0.0.1:3306/demo_ds_0?serverTimezone=UTC&useSSL=false - username: root - password: - autoCommit: true - connectionTimeout: 30000 - idleTimeout: 60000 - maxLifetime: 1800000 - maximumPoolSize: 50 - ds_1: - url: jdbc:mysql://127.0.0.1:3306/demo_ds_1?serverTimezone=UTC&useSSL=false - username: root - password: - autoCommit: true - connectionTimeout: 30000 - idleTimeout: 60000 - maxLifetime: 1800000 - maximumPoolSize: 50 - -shardingRule: - tables: - t_order: - actualDataNodes: ds_${0..1}.t_order_${0..1} - tableStrategy: - inline: - shardingColumn: order_id - algorithmExpression: t_order_${order_id % 2} - keyGeneratorColumnName: order_id - t_order_item: - actualDataNodes: ds_${0..1}.t_order_item_${0..1} - tableStrategy: - inline: - shardingColumn: order_id - algorithmExpression: t_order_item_${order_id % 2} - keyGeneratorColumnName: order_item_id - bindingTables: - - t_order,t_order_item - defaultDatabaseStrategy: - inline: - shardingColumn: user_id - algorithmExpression: ds_${user_id % 2} - defaultTableStrategy: - none: - defaultKeyGeneratorClassName: io.shardingsphere.core.keygen.DefaultKeyGenerator +#schemaName: sharding_db +# +#dataSources: +# ds_0: +# url: jdbc:mysql://127.0.0.1:3306/demo_ds_0?serverTimezone=UTC&useSSL=false +# username: root +# password: +# autoCommit: true +# connectionTimeout: 30000 +# idleTimeout: 60000 +# maxLifetime: 1800000 +# maximumPoolSize: 50 +# ds_1: +# url: jdbc:mysql://127.0.0.1:3306/demo_ds_1?serverTimezone=UTC&useSSL=false +# username: root +# password: +# autoCommit: true +# connectionTimeout: 30000 +# idleTimeout: 60000 +# maxLifetime: 1800000 +# maximumPoolSize: 50 +# +#shardingRule: +# tables: +# t_order: +# actualDataNodes: ds_${0..1}.t_order_${0..1} +# tableStrategy: +# inline: +# shardingColumn: order_id +# algorithmExpression: t_order_${order_id % 2} +# keyGeneratorColumnName: order_id +# t_order_item: +# actualDataNodes: ds_${0..1}.t_order_item_${0..1} +# tableStrategy: +# inline: +# shardingColumn: order_id +# algorithmExpression: t_order_item_${order_id % 2} +# keyGeneratorColumnName: order_item_id +# bindingTables: +# - t_order,t_order_item +# defaultDatabaseStrategy: +# inline: +# shardingColumn: user_id +# algorithmExpression: ds_${user_id % 2} +# defaultTableStrategy: +# none: +# defaultKeyGeneratorClassName: io.shardingsphere.core.keygen.DefaultKeyGenerator diff --git a/sharding-proxy/src/main/resources/conf/server.yaml b/sharding-proxy/src/main/resources/conf/server.yaml index d5405020b7e9b..c19de987e55bb 100644 --- a/sharding-proxy/src/main/resources/conf/server.yaml +++ b/sharding-proxy/src/main/resources/conf/server.yaml @@ -11,21 +11,21 @@ # serverLists: localhost:2181 # namespace: orchestration # -authentication: - username: root - password: root - -props: - max.connections.size.per.query: 8 - acceptor.size: 16 # The default value is available processors count * 2. - executor.size: 16 # Infinite by default. - # LOCAL: Proxy will run with LOCAL transaction. - # XA: Proxy will run with XA transaction. - # BASE: Proxy will run with B.A.S.E transaction. - proxy.transaction.type: LOCAL - proxy.opentracing.enabled: false - sql.show: false - +#authentication: +# username: root +# password: root +# +#props: +# max.connections.size.per.query: 1 +# acceptor.size: 16 # The default value is available processors count * 2. +# executor.size: 16 # Infinite by default. +# # LOCAL: Proxy will run with LOCAL transaction. +# # XA: Proxy will run with XA transaction. +# # BASE: Proxy will run with B.A.S.E transaction. +# proxy.transaction.type: LOCAL +# proxy.opentracing.enabled: false +# sql.show: false +# #configMap: # sharding-key1: sharding-value1 # sharding-key2: sharding-value2 From 9ba23a29e745baf43cd4b1cf109c35761703a3a8 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Thu, 22 Nov 2018 19:00:02 +0800 Subject: [PATCH 111/113] resolve conflict. --- .../shardingproxy/backend/BackendHandlerFactory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/BackendHandlerFactory.java b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/BackendHandlerFactory.java index d79bc44fde091..52a2601880367 100644 --- a/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/BackendHandlerFactory.java +++ b/sharding-proxy/src/main/java/io/shardingsphere/shardingproxy/backend/BackendHandlerFactory.java @@ -116,7 +116,7 @@ public static BackendHandler createBackendHandler( final int connectionId, final int sequenceId, final String sql, final BackendConnection backendConnection, final DatabaseType databaseType, final FrontendHandler frontendHandler) { SQLStatement sqlStatement = new SQLJudgeEngine(sql).judge(); if (SQLType.DCL == sqlStatement.getType() || sqlStatement instanceof SetStatement) { - return new SchemaBroadcastBackendHandler(connectionId, sequenceId, sql, databaseType); + return new SchemaBroadcastBackendHandler(connectionId, sequenceId, sql, backendConnection, databaseType); } if (sqlStatement instanceof UseStatement || sqlStatement instanceof ShowDatabasesStatement) { From 3ab3204816759c9168c557e454d40da05041be15 Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Thu, 22 Nov 2018 22:45:15 +0800 Subject: [PATCH 112/113] Resolve test error for MySQLFrontendHandlerTest --- .../frontend/mysql/MySQLFrontendHandlerTest.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/frontend/mysql/MySQLFrontendHandlerTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/frontend/mysql/MySQLFrontendHandlerTest.java index b4bd9a8e18058..6a6a64bb6d7ec 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/frontend/mysql/MySQLFrontendHandlerTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/frontend/mysql/MySQLFrontendHandlerTest.java @@ -33,6 +33,7 @@ import io.shardingsphere.shardingproxy.transport.mysql.packet.handshake.HandshakePacket; import lombok.SneakyThrows; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -57,6 +58,14 @@ public final class MySQLFrontendHandlerTest { @Mock private ChannelHandlerContext context; + @BeforeClass + @SneakyThrows + public static void beforeClass() { + Field field = GlobalRegistry.getInstance().getClass().getDeclaredField("shardingProperties"); + field.setAccessible(true); + field.set(GlobalRegistry.getInstance(), new ShardingProperties(new Properties())); + } + @Before @SneakyThrows public void resetConnectionIdGenerator() { From 624b02f2affc57a0056a115e7aaa3b9ee063912b Mon Sep 17 00:00:00 2001 From: cherrylzhao Date: Thu, 22 Nov 2018 22:47:45 +0800 Subject: [PATCH 113/113] Resolve test error for FrontendHandlerFactoryTest. --- .../common/FrontendHandlerFactoryTest.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/frontend/common/FrontendHandlerFactoryTest.java b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/frontend/common/FrontendHandlerFactoryTest.java index 15704b2288ab4..fd7e855312ab2 100644 --- a/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/frontend/common/FrontendHandlerFactoryTest.java +++ b/sharding-proxy/src/test/java/io/shardingsphere/shardingproxy/frontend/common/FrontendHandlerFactoryTest.java @@ -18,14 +18,29 @@ package io.shardingsphere.shardingproxy.frontend.common; import io.shardingsphere.core.constant.DatabaseType; +import io.shardingsphere.core.constant.properties.ShardingProperties; import io.shardingsphere.shardingproxy.frontend.mysql.MySQLFrontendHandler; +import io.shardingsphere.shardingproxy.runtime.GlobalRegistry; +import lombok.SneakyThrows; +import org.junit.BeforeClass; import org.junit.Test; +import java.lang.reflect.Field; +import java.util.Properties; + import static org.hamcrest.CoreMatchers.instanceOf; import static org.junit.Assert.assertThat; public final class FrontendHandlerFactoryTest { + @BeforeClass + @SneakyThrows + public static void beforeClass() { + Field field = GlobalRegistry.getInstance().getClass().getDeclaredField("shardingProperties"); + field.setAccessible(true); + field.set(GlobalRegistry.getInstance(), new ShardingProperties(new Properties())); + } + @Test public void assertCreateFrontendHandlerInstanceWithMySQL() { assertThat(FrontendHandlerFactory.createFrontendHandlerInstance(DatabaseType.MySQL, null), instanceOf(MySQLFrontendHandler.class));