diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/HintManager.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/HintManager.java index 84f2c1343f6f0..5f44d2f29f3aa 100644 --- a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/HintManager.java +++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/api/HintManager.java @@ -44,6 +44,9 @@ public final class HintManager implements AutoCloseable { private final Map> tableShardingValues = new HashMap<>(); + @Getter + private boolean shardingHint; + @Getter private boolean masterRouteOnly; @@ -80,6 +83,7 @@ public void addDatabaseShardingValue(final String logicTable, final String shard * @param values 分片值 */ public void addDatabaseShardingValue(final String logicTable, final String shardingColumn, final Condition.BinaryOperator binaryOperator, final Comparable... values) { + shardingHint = true; databaseShardingValues.put(new ShardingKey(logicTable, shardingColumn), getShardingValue(logicTable, shardingColumn, binaryOperator, values)); } @@ -105,6 +109,7 @@ public void addTableShardingValue(final String logicTable, final String sharding * @param values 分片值 */ public void addTableShardingValue(final String logicTable, final String shardingColumn, final Condition.BinaryOperator binaryOperator, final Comparable... values) { + shardingHint = true; tableShardingValues.put(new ShardingKey(logicTable, shardingColumn), getShardingValue(logicTable, shardingColumn, binaryOperator, values)); } diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/hint/HintManagerHolder.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/hint/HintManagerHolder.java index 0d70b90bb0d2d..d08d93db36e80 100644 --- a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/hint/HintManagerHolder.java +++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/hint/HintManagerHolder.java @@ -48,8 +48,8 @@ public static void setHintManager(final HintManager hintManager) { * 判断当前线程是否使用线索分片. * @return 当前线程是否使用线索分片 */ - public static boolean isUseHint() { - return null != HINT_MANAGER_HOLDER.get(); + public static boolean isUseShardingHint() { + return null != HINT_MANAGER_HOLDER.get() && HINT_MANAGER_HOLDER.get().isShardingHint(); } /** @@ -59,7 +59,7 @@ public static boolean isUseHint() { * @return 分库分片键值 */ public static Optional> getDatabaseShardingValue(final ShardingKey shardingKey) { - return isUseHint() ? Optional.>fromNullable(HINT_MANAGER_HOLDER.get().getDatabaseShardingValue(shardingKey)) : Optional.>absent(); + return isUseShardingHint() ? Optional.>fromNullable(HINT_MANAGER_HOLDER.get().getDatabaseShardingValue(shardingKey)) : Optional.>absent(); } /** @@ -69,7 +69,7 @@ public static Optional> getDatabaseShardingValue(final Sharding * @return 分表分片键值 */ public static Optional> getTableShardingValue(final ShardingKey shardingKey) { - return isUseHint() ? Optional.>fromNullable(HINT_MANAGER_HOLDER.get().getTableShardingValue(shardingKey)) : Optional.>absent(); + return isUseShardingHint() ? Optional.>fromNullable(HINT_MANAGER_HOLDER.get().getTableShardingValue(shardingKey)) : Optional.>absent(); } /** @@ -78,7 +78,18 @@ public static Optional> getTableShardingValue(final ShardingKey * @return 是否数据库操作只路由至主库 */ public static boolean isMasterRouteOnly() { - return isUseHint() ? HINT_MANAGER_HOLDER.get().isMasterRouteOnly() : false; + return null != HINT_MANAGER_HOLDER.get() && HINT_MANAGER_HOLDER.get().isMasterRouteOnly(); + } + + /** + * 设置数据库操作只路由至主库. + */ + public static void setMasterRouteOnly() { + if (null != HINT_MANAGER_HOLDER.get()) { + HINT_MANAGER_HOLDER.get().setMasterRouteOnly(); + } else { + HintManager.getInstance().setMasterRouteOnly(); + } } /** diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/MasterSlaveDataSource.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/MasterSlaveDataSource.java index 2f0dfa564be94..b3bff3b318558 100644 --- a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/MasterSlaveDataSource.java +++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/jdbc/MasterSlaveDataSource.java @@ -38,14 +38,6 @@ @RequiredArgsConstructor public final class MasterSlaveDataSource extends AbstractDataSourceAdapter { - private static final ThreadLocal WAS_UPDATED = new ThreadLocal() { - - @Override - protected Boolean initialValue() { - return false; - } - }; - private final String name; private final DataSource masterDataSource; @@ -61,8 +53,8 @@ protected Boolean initialValue() { * @return 主或从节点的数据源 */ public DataSource getDataSource(final SQLStatementType sqlStatementType) { - if (SQLStatementType.SELECT != sqlStatementType || WAS_UPDATED.get() || HintManagerHolder.isMasterRouteOnly()) { - WAS_UPDATED.set(true); + if (SQLStatementType.SELECT != sqlStatementType || HintManagerHolder.isMasterRouteOnly()) { + HintManagerHolder.setMasterRouteOnly(); return masterDataSource; } return slaveLoadBalanceStrategy.getDataSource(name, slaveDataSources); diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/router/single/SingleTableRouter.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/router/single/SingleTableRouter.java index 36c9b7cd25579..a21379bd4d011 100644 --- a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/router/single/SingleTableRouter.java +++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/router/single/SingleTableRouter.java @@ -100,7 +100,7 @@ public SingleRoutingResult route() { private Collection routeDataSources() { DatabaseShardingStrategy strategy = shardingRule.getDatabaseShardingStrategy(tableRule); List> shardingValues; - if (HintManagerHolder.isUseHint()) { + if (HintManagerHolder.isUseShardingHint()) { shardingValues = getDatabaseShardingValuesFromHint(strategy.getShardingColumns()); } else { shardingValues = getShardingValues(strategy.getShardingColumns()); @@ -115,7 +115,7 @@ private Collection routeDataSources() { private Collection routeTables(final Collection routedDataSources) { TableShardingStrategy strategy = shardingRule.getTableShardingStrategy(tableRule); List> shardingValues; - if (HintManagerHolder.isUseHint()) { + if (HintManagerHolder.isUseShardingHint()) { shardingValues = getTableShardingValuesFromHint(strategy.getShardingColumns()); } else { shardingValues = getShardingValues(strategy.getShardingColumns()); diff --git a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/masterslave/AbstractShardingMasterSlaveDBUnitTest.java b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/masterslave/AbstractShardingMasterSlaveDBUnitTest.java index 70523b19fbce7..724da9710e036 100644 --- a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/masterslave/AbstractShardingMasterSlaveDBUnitTest.java +++ b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/masterslave/AbstractShardingMasterSlaveDBUnitTest.java @@ -26,13 +26,13 @@ import com.dangdang.ddframe.rdb.sharding.api.rule.TableRule; import com.dangdang.ddframe.rdb.sharding.api.strategy.database.DatabaseShardingStrategy; import com.dangdang.ddframe.rdb.sharding.api.strategy.table.TableShardingStrategy; +import com.dangdang.ddframe.rdb.sharding.hint.HintManagerHolder; import com.dangdang.ddframe.rdb.sharding.jdbc.MasterSlaveDataSource; import com.dangdang.ddframe.rdb.sharding.jdbc.ShardingDataSource; import org.junit.After; import org.junit.Before; import javax.sql.DataSource; -import java.lang.reflect.Field; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; @@ -46,9 +46,7 @@ public abstract class AbstractShardingMasterSlaveDBUnitTest extends AbstractDBUn @Before @After public void reset() throws NoSuchFieldException, IllegalAccessException { - Field field = MasterSlaveDataSource.class.getDeclaredField("WAS_UPDATED"); - field.setAccessible(true); - ((ThreadLocal) field.get(MasterSlaveDataSource.class)).remove(); + HintManagerHolder.clear(); } @Override @@ -103,16 +101,26 @@ protected List getDataSetFiles() { protected final ShardingDataSource getShardingDataSource() { Map masterSlaveDataSourceMap = createDataSourceMap(dataSourceName); - MasterSlaveDataSource masterSlaveDs0 = new MasterSlaveDataSource("ms_0", masterSlaveDataSourceMap.get("dataSource_master_0"), Collections.singletonList(masterSlaveDataSourceMap.get("dataSource_slave_0"))); - MasterSlaveDataSource masterSlaveDs1 = new MasterSlaveDataSource("ms_1", masterSlaveDataSourceMap.get("dataSource_master_1"), Collections.singletonList(masterSlaveDataSourceMap.get("dataSource_slave_1"))); - MasterSlaveDataSource masterSlaveDs2 = new MasterSlaveDataSource("ms_2", masterSlaveDataSourceMap.get("dataSource_master_2"), Collections.singletonList(masterSlaveDataSourceMap.get("dataSource_slave_2"))); - MasterSlaveDataSource masterSlaveDs3 = new MasterSlaveDataSource("ms_3", masterSlaveDataSourceMap.get("dataSource_master_3"), Collections.singletonList(masterSlaveDataSourceMap.get("dataSource_slave_3"))); - MasterSlaveDataSource masterSlaveDs4 = new MasterSlaveDataSource("ms_4", masterSlaveDataSourceMap.get("dataSource_master_4"), Collections.singletonList(masterSlaveDataSourceMap.get("dataSource_slave_4"))); - MasterSlaveDataSource masterSlaveDs5 = new MasterSlaveDataSource("ms_5", masterSlaveDataSourceMap.get("dataSource_master_5"), Collections.singletonList(masterSlaveDataSourceMap.get("dataSource_slave_5"))); - MasterSlaveDataSource masterSlaveDs6 = new MasterSlaveDataSource("ms_6", masterSlaveDataSourceMap.get("dataSource_master_6"), Collections.singletonList(masterSlaveDataSourceMap.get("dataSource_slave_6"))); - MasterSlaveDataSource masterSlaveDs7 = new MasterSlaveDataSource("ms_7", masterSlaveDataSourceMap.get("dataSource_master_7"), Collections.singletonList(masterSlaveDataSourceMap.get("dataSource_slave_7"))); - MasterSlaveDataSource masterSlaveDs8 = new MasterSlaveDataSource("ms_8", masterSlaveDataSourceMap.get("dataSource_master_8"), Collections.singletonList(masterSlaveDataSourceMap.get("dataSource_slave_8"))); - MasterSlaveDataSource masterSlaveDs9 = new MasterSlaveDataSource("ms_9", masterSlaveDataSourceMap.get("dataSource_master_9"), Collections.singletonList(masterSlaveDataSourceMap.get("dataSource_slave_9"))); + MasterSlaveDataSource masterSlaveDs0 = new MasterSlaveDataSource("ms_0", masterSlaveDataSourceMap.get("dataSource_master_0"), + Collections.singletonList(masterSlaveDataSourceMap.get("dataSource_slave_0"))); + MasterSlaveDataSource masterSlaveDs1 = new MasterSlaveDataSource("ms_1", masterSlaveDataSourceMap.get("dataSource_master_1"), + Collections.singletonList(masterSlaveDataSourceMap.get("dataSource_slave_1"))); + MasterSlaveDataSource masterSlaveDs2 = new MasterSlaveDataSource("ms_2", masterSlaveDataSourceMap.get("dataSource_master_2"), + Collections.singletonList(masterSlaveDataSourceMap.get("dataSource_slave_2"))); + MasterSlaveDataSource masterSlaveDs3 = new MasterSlaveDataSource("ms_3", masterSlaveDataSourceMap.get("dataSource_master_3"), + Collections.singletonList(masterSlaveDataSourceMap.get("dataSource_slave_3"))); + MasterSlaveDataSource masterSlaveDs4 = new MasterSlaveDataSource("ms_4", masterSlaveDataSourceMap.get("dataSource_master_4"), + Collections.singletonList(masterSlaveDataSourceMap.get("dataSource_slave_4"))); + MasterSlaveDataSource masterSlaveDs5 = new MasterSlaveDataSource("ms_5", masterSlaveDataSourceMap.get("dataSource_master_5"), + Collections.singletonList(masterSlaveDataSourceMap.get("dataSource_slave_5"))); + MasterSlaveDataSource masterSlaveDs6 = new MasterSlaveDataSource("ms_6", masterSlaveDataSourceMap.get("dataSource_master_6"), + Collections.singletonList(masterSlaveDataSourceMap.get("dataSource_slave_6"))); + MasterSlaveDataSource masterSlaveDs7 = new MasterSlaveDataSource("ms_7", masterSlaveDataSourceMap.get("dataSource_master_7"), + Collections.singletonList(masterSlaveDataSourceMap.get("dataSource_slave_7"))); + MasterSlaveDataSource masterSlaveDs8 = new MasterSlaveDataSource("ms_8", masterSlaveDataSourceMap.get("dataSource_master_8"), + Collections.singletonList(masterSlaveDataSourceMap.get("dataSource_slave_8"))); + MasterSlaveDataSource masterSlaveDs9 = new MasterSlaveDataSource("ms_9", masterSlaveDataSourceMap.get("dataSource_master_9"), + Collections.singletonList(masterSlaveDataSourceMap.get("dataSource_slave_9"))); Map dataSourceMap = new HashMap<>(10); dataSourceMap.put("ms_0", masterSlaveDs0); dataSourceMap.put("ms_1", masterSlaveDs1); diff --git a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/masterslave/pstatement/ShardingMasterSlaveForPStatementWithDMLTest.java b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/masterslave/pstatement/ShardingMasterSlaveForPStatementWithDMLTest.java index 3a16bc0d07003..fecfab6e9e7d6 100644 --- a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/masterslave/pstatement/ShardingMasterSlaveForPStatementWithDMLTest.java +++ b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/masterslave/pstatement/ShardingMasterSlaveForPStatementWithDMLTest.java @@ -18,6 +18,7 @@ package com.dangdang.ddframe.rdb.integrate.masterslave.pstatement; import com.dangdang.ddframe.rdb.integrate.masterslave.AbstractShardingMasterSlaveDBUnitTest; +import com.dangdang.ddframe.rdb.sharding.api.HintManager; import com.dangdang.ddframe.rdb.sharding.jdbc.ShardingDataSource; import com.dangdang.ddframe.rdb.sharding.parser.result.router.SQLStatementType; import org.dbunit.DatabaseUnitException; @@ -57,6 +58,31 @@ public void assertInsertWithAllPlaceholders() throws SQLException, DatabaseUnitE assertDataSet("insert", "insert"); } + @Test + public void assertInsertWithHint() throws SQLException, DatabaseUnitException { + String sql = "INSERT INTO `t_order` (`order_id`, `user_id`, `status`) VALUES (?, ?, ?)"; + for (int i = 1; i <= 10; i++) { + for (int j = 1; j <= 10; j++) { + try ( + Connection connection = shardingDataSource.getConnection(); + HintManager hintManager = HintManager.getInstance() + ) { + hintManager.addDatabaseShardingValue("t_order", "user_id", j); + hintManager.addTableShardingValue("t_order", "order_id", i); + PreparedStatement preparedStatement = connection.prepareStatement(sql); + preparedStatement.setInt(1, i); + preparedStatement.setInt(2, j); + preparedStatement.setString(3, "insert"); + preparedStatement.executeUpdate(); + } + } + } + try (HintManager hintManager = HintManager.getInstance()) { + hintManager.setMasterRouteOnly(); + assertDataSet("insert", "insert"); + } + } + @Test public void assertInsertWithoutPlaceholder() throws SQLException, DatabaseUnitException { String sql = "INSERT INTO `t_order` (`order_id`, `user_id`, `status`) VALUES (%s, %s, 'insert')"; diff --git a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/masterslave/pstatement/ShardingMasterSlaveForPStatementWithSelectTest.java b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/masterslave/pstatement/ShardingMasterSlaveForPStatementWithSelectTest.java index 65520d4023c93..a61e8598d0576 100644 --- a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/masterslave/pstatement/ShardingMasterSlaveForPStatementWithSelectTest.java +++ b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/integrate/masterslave/pstatement/ShardingMasterSlaveForPStatementWithSelectTest.java @@ -18,6 +18,7 @@ package com.dangdang.ddframe.rdb.integrate.masterslave.pstatement; import com.dangdang.ddframe.rdb.integrate.masterslave.AbstractShardingMasterSlaveDBUnitTest; +import com.dangdang.ddframe.rdb.sharding.api.HintManager; import com.dangdang.ddframe.rdb.sharding.jdbc.ShardingDataSource; import org.dbunit.DatabaseUnitException; import org.junit.Before; @@ -95,4 +96,23 @@ public void assertSelectGroupByWithoutGroupedColumn() throws SQLException, Datab assertDataSet("integrate/dataset/masterslave/expect/select/SelectGroupByWithBindingTable.xml", getShardingDataSource().getConnection(), "t_order_item", sql, 10, 19, 1000, 1909); assertDataSet("integrate/dataset/Empty.xml", getShardingDataSource().getConnection(), "t_order_item", sql, 1, 9, 1000, 1909); } + + @Test + public void assertSelectForHint() throws SQLException, DatabaseUnitException { + HintManager hintManager = HintManager.getInstance(); + hintManager.addDatabaseShardingValue("t_order", "user_id", 10); + hintManager.addTableShardingValue("t_order", "order_id", 1000); + String sql = "SELECT `t_order`.order_id, `t_order`.user_id, `t_order`.status FROM `t_order` WHERE `t_order`.`user_id` = ? AND `t_order`.`order_id` = ?"; + assertDataSet("integrate/dataset/masterslave/expect/select/SelectEqualsWithSingleTable_0.xml", shardingDataSource.getConnection(), "t_order", sql, 10, 1000); + } + + @Test + public void assertSelectForHintAndForceMaster() throws SQLException, DatabaseUnitException { + HintManager hintManager = HintManager.getInstance(); + hintManager.setMasterRouteOnly(); + hintManager.addDatabaseShardingValue("t_order", "user_id", 10); + hintManager.addTableShardingValue("t_order", "order_id", 1000); + String sql = "SELECT `t_order`.order_id, `t_order`.user_id, `t_order`.status FROM `t_order` WHERE `t_order`.`user_id` = ? AND `t_order`.`order_id` = ?"; + assertDataSet("integrate/dataset/masterslave/expect/select/SelectEqualsWithSingleMasterTable_0.xml", shardingDataSource.getConnection(), "t_order", sql, 10, 1000); + } } diff --git a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/hint/HintManagerHolderTest.java b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/hint/HintManagerHolderTest.java index 60bac8550f068..f278db8d81afc 100644 --- a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/hint/HintManagerHolderTest.java +++ b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/hint/HintManagerHolderTest.java @@ -38,28 +38,65 @@ public void assertSetHintManagerTwice() { HintManagerHolder.setHintManager(HintManager.getInstance()); } + @Test + public void assertsUseShardingHintWithoutAddShardingColumns() { + assertFalse(HintManagerHolder.isUseShardingHint()); + } + + @Test + public void assertsUseShardingHintWithoutSetHintManager() { + hintManager.close(); + assertFalse(HintManagerHolder.isUseShardingHint()); + } + + @Test + public void assertsUseShardingHintWithAddShardingColumns() { + hintManager.addDatabaseShardingValue("logicTable", "shardingColumn", 1); + assertTrue(HintManagerHolder.isUseShardingHint()); + } + @Test public void assertGetDatabaseShardingValue() { hintManager.addDatabaseShardingValue("logicTable", "shardingColumn", 1); assertTrue(HintManagerHolder.getDatabaseShardingValue(new ShardingKey("logicTable", "shardingColumn")).isPresent()); + assertTrue(HintManagerHolder.isUseShardingHint()); } @Test public void assertGetTableShardingValue() { hintManager.addTableShardingValue("logicTable", "shardingColumn", 1); assertTrue(HintManagerHolder.getTableShardingValue(new ShardingKey("logicTable", "shardingColumn")).isPresent()); + assertTrue(HintManagerHolder.isUseShardingHint()); } @Test public void assertIsMasterRouteOnlyWithoutSet() { hintManager.close(); assertFalse(HintManagerHolder.isMasterRouteOnly()); + assertFalse(HintManagerHolder.isUseShardingHint()); } @Test public void assertIsMasterRouteOnly() { hintManager.setMasterRouteOnly(); assertTrue(HintManagerHolder.isMasterRouteOnly()); + assertFalse(HintManagerHolder.isUseShardingHint()); + } + + @Test + public void assertSetMasterRouteOnlyWithHint() { + HintManagerHolder.setMasterRouteOnly(); + assertTrue(HintManagerHolder.isMasterRouteOnly()); + assertFalse(HintManagerHolder.isUseShardingHint()); + } + + @Test + public void assertSetMasterRouteOnlyWithoutHint() { + hintManager.close(); + assertFalse(HintManagerHolder.isMasterRouteOnly()); + HintManagerHolder.setMasterRouteOnly(); + assertTrue(HintManagerHolder.isMasterRouteOnly()); + assertFalse(HintManagerHolder.isUseShardingHint()); } @Test diff --git a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/MasterSlaveDataSourceTest.java b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/MasterSlaveDataSourceTest.java index 9036fc29fe2ec..ce78dc9f046fa 100644 --- a/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/MasterSlaveDataSourceTest.java +++ b/sharding-jdbc-core/src/test/java/com/dangdang/ddframe/rdb/sharding/jdbc/MasterSlaveDataSourceTest.java @@ -20,13 +20,13 @@ import com.dangdang.ddframe.rdb.sharding.api.HintManager; import com.dangdang.ddframe.rdb.sharding.api.MasterSlaveDataSourceFactory; import com.dangdang.ddframe.rdb.sharding.fixture.TestDataSource; +import com.dangdang.ddframe.rdb.sharding.hint.HintManagerHolder; import com.dangdang.ddframe.rdb.sharding.parser.result.router.SQLStatementType; import org.junit.After; import org.junit.Before; import org.junit.Test; import javax.sql.DataSource; -import java.lang.reflect.Field; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.SQLException; @@ -48,10 +48,8 @@ public final class MasterSlaveDataSourceTest { @Before @After - public void reset() throws NoSuchFieldException, IllegalAccessException { - Field field = MasterSlaveDataSource.class.getDeclaredField("WAS_UPDATED"); - field.setAccessible(true); - ((ThreadLocal) field.get(MasterSlaveDataSource.class)).remove(); + public void reset() { + HintManagerHolder.clear(); } @Test diff --git a/sharding-jdbc-core/src/test/resources/integrate/dataset/masterslave/expect/select/SelectEqualsWithSingleMasterTable_0.xml b/sharding-jdbc-core/src/test/resources/integrate/dataset/masterslave/expect/select/SelectEqualsWithSingleMasterTable_0.xml new file mode 100644 index 0000000000000..9eb4ed18a71b6 --- /dev/null +++ b/sharding-jdbc-core/src/test/resources/integrate/dataset/masterslave/expect/select/SelectEqualsWithSingleMasterTable_0.xml @@ -0,0 +1,3 @@ + + + diff --git a/sharding-jdbc-doc/content/post/master_slave.md b/sharding-jdbc-doc/content/post/master_slave.md index 8e5d5e8181414..0c9a51a8d9e0f 100644 --- a/sharding-jdbc-doc/content/post/master_slave.md +++ b/sharding-jdbc-doc/content/post/master_slave.md @@ -10,10 +10,9 @@ weight = 6 ## 支持项 1. 提供了一主多从的读写分离配置,可配合分库分表使用。 -1. 同一线程如果有写入操作,以后的读操作均从主库读取,用于保证同一线程中的数据一致性。 -1. Spring命名空间。 -1. 基于Hint的强制主库路由。 - +1. 同一`HintManager`生命周期内,如有写入操作,以后的读操作均从主库读取,用于保证同一线程中的数据一致性。 +1. `Spring`命名空间。 +1. 基于`Hint`的强制主库路由。 ## 不支持范围 1. 主库和从库的数据同步。 diff --git a/sharding-jdbc-doc/content/post/release_notes.md b/sharding-jdbc-doc/content/post/release_notes.md index d474a34544f6a..4ac1ccfa4ca91 100644 --- a/sharding-jdbc-doc/content/post/release_notes.md +++ b/sharding-jdbc-doc/content/post/release_notes.md @@ -8,6 +8,10 @@ weight = 1 ## 1.3.1-SNAPSHOT +### 缺陷修正 + +1. [ISSUE #89](https://github.com/dangdangdotcom/sharding-jdbc/issues/89) 读写分离和分片的hint一起使用导致冲突 + ## 1.3.0 ### 新功能