From ec657f6c0040584b430664468ca58edb4deffa3d Mon Sep 17 00:00:00 2001 From: gaohongtao Date: Thu, 20 Oct 2016 11:56:48 +0800 Subject: [PATCH] fix #122 bed get new connection when old one is broken --- .../rdb/sharding/jdbc/ShardingConnection.java | 29 ++++++++++++++----- .../sharding/jdbc/ShardingConnectionTest.java | 7 +++++ .../content/post/release_notes.md | 1 + .../bed/sync/BestEffortsDeliveryListener.java | 5 ++-- 4 files changed, 33 insertions(+), 9 deletions(-) diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingConnection.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingConnection.java index 86a7e7c5e46b8..d337405077825 100644 --- a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingConnection.java +++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingConnection.java @@ -24,6 +24,7 @@ import com.dangdang.ddframe.rdb.sharding.parser.result.router.SQLStatementType; import com.google.common.base.Joiner; import com.google.common.base.Optional; +import com.google.common.base.Preconditions; import lombok.AccessLevel; import lombok.Getter; import lombok.RequiredArgsConstructor; @@ -65,6 +66,26 @@ public Connection getConnection(final String dataSourceName, final SQLStatementT return result; } + /** + * 释放缓存中已经中断的数据库连接. + * + * @param brokenConnection 已经中断的数据库连接 + */ + public void releaseBrokenConnection(final Connection brokenConnection) { + Preconditions.checkNotNull(brokenConnection); + closeConnection(brokenConnection); + connectionMap.values().remove(brokenConnection); + } + + private void closeConnection(final Connection connection) { + if (null != connection) { + try { + connection.close(); + } catch (final SQLException ignored) { + } + } + } + @Override public DatabaseMetaData getMetaData() throws SQLException { return getConnection(shardingContext.getShardingRule().getDataSourceRule().getDataSourceNames().iterator().next(), SQLStatementType.SELECT).getMetaData(); @@ -93,13 +114,7 @@ private String getRealDataSourceName(final String dataSourceName, final SQLState if (!MasterSlaveDataSource.isDML(sqlStatementType)) { return slaveDataSourceName; } - Connection slaveConnection = connectionMap.remove(slaveDataSourceName); - if (null != slaveConnection) { - try { - slaveConnection.close(); - } catch (final SQLException ignored) { - } - } + closeConnection(connectionMap.remove(slaveDataSourceName)); return getMasterDataSourceName(dataSourceName); } diff --git a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingConnectionTest.java b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingConnectionTest.java index e1cbcfddba774..f137c8a6a6d7c 100644 --- a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingConnectionTest.java +++ b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/ShardingConnectionTest.java @@ -103,4 +103,11 @@ public void getConnectionMixed() throws Exception { assertSame(masterConnection, connection.getConnection(DS_NAME, SQLStatementType.SELECT)); assertSame(masterConnection, connection.getConnection(DS_NAME, SQLStatementType.UPDATE)); } + + @Test + public void releaseBrokenConnectionTest() throws Exception { + Connection conn = connection.getConnection(DS_NAME, SQLStatementType.UPDATE); + connection.releaseBrokenConnection(conn); + assertNotSame(conn, connection.getConnection(DS_NAME, SQLStatementType.UPDATE)); + } } \ No newline at end of file diff --git a/sharding-jdbc-doc/content/post/release_notes.md b/sharding-jdbc-doc/content/post/release_notes.md index fc2ad4266eb5e..d6c74b4fd75c2 100644 --- a/sharding-jdbc-doc/content/post/release_notes.md +++ b/sharding-jdbc-doc/content/post/release_notes.md @@ -19,6 +19,7 @@ weight = 1 1. [ISSUE #149](https://github.com/dangdangdotcom/sharding-jdbc/issues/149) INSERT IGNORE INTO时如果数据重了忽略时返回的成-1了,应该返回0 1. [ISSUE #118](https://github.com/dangdangdotcom/sharding-jdbc/issues/118) 同一个线程内先执行DQL后执行DML,DML操作在从库上执行 +1. [ISSUE #122](https://github.com/dangdangdotcom/sharding-jdbc/issues/122) bed的fail重试问题 ## 1.3.2 diff --git a/sharding-jdbc-transaction-parent/sharding-jdbc-transaction/src/main/java/com/dangdang/ddframe/rdb/transaction/soft/bed/sync/BestEffortsDeliveryListener.java b/sharding-jdbc-transaction-parent/sharding-jdbc-transaction/src/main/java/com/dangdang/ddframe/rdb/transaction/soft/bed/sync/BestEffortsDeliveryListener.java index 1de2aa308c6d2..a741610408bdd 100644 --- a/sharding-jdbc-transaction-parent/sharding-jdbc-transaction/src/main/java/com/dangdang/ddframe/rdb/transaction/soft/bed/sync/BestEffortsDeliveryListener.java +++ b/sharding-jdbc-transaction-parent/sharding-jdbc-transaction/src/main/java/com/dangdang/ddframe/rdb/transaction/soft/bed/sync/BestEffortsDeliveryListener.java @@ -72,9 +72,10 @@ public void listen(final DMLExecutionEvent event) { Connection conn = null; PreparedStatement preparedStatement = null; try { - conn = bedSoftTransaction.getConnection().getConnection(event.getDataSource(), SQLStatementType.SELECT); + conn = bedSoftTransaction.getConnection().getConnection(event.getDataSource(), SQLStatementType.UPDATE); if (!isValidConnection(conn)) { - conn = bedSoftTransaction.getConnection(); + bedSoftTransaction.getConnection().releaseBrokenConnection(conn); + conn = bedSoftTransaction.getConnection().getConnection(event.getDataSource(), SQLStatementType.UPDATE); isNewConnection = true; } preparedStatement = conn.prepareStatement(event.getSql());