Skip to content

Commit

Permalink
for #85 use hint set force route from master
Browse files Browse the repository at this point in the history
  • Loading branch information
terrymanu committed May 31, 2016
1 parent efbce58 commit 5980c97
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.google.common.collect.BoundType;
import com.google.common.collect.Range;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.Arrays;
Expand All @@ -43,6 +44,9 @@ public final class HintManager implements AutoCloseable {

private final Map<ShardingKey, ShardingValue<?>> tableShardingValues = new HashMap<>();

@Getter
private boolean masterRouteOnly;

/**
* 获取线索分片管理器实例.
*
Expand Down Expand Up @@ -139,6 +143,13 @@ public ShardingValue<?> getTableShardingValue(final ShardingKey shardingKey) {
return tableShardingValues.get(shardingKey);
}

/**
* 设置数据库操作只路由至主库.
*/
public void setMasterRouteOnly() {
masterRouteOnly = true;
}

@Override
public void close() {
HintManagerHolder.clear();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,15 @@ public static Optional<ShardingValue<?>> getTableShardingValue(final ShardingKey
return isUseHint() ? Optional.<ShardingValue<?>>fromNullable(HINT_MANAGER_HOLDER.get().getTableShardingValue(shardingKey)) : Optional.<ShardingValue<?>>absent();
}

/**
* 判断是否数据库操作只路由至主库.
*
* @return 是否数据库操作只路由至主库
*/
public static boolean isMasterRouteOnly() {
return isUseHint() ? HINT_MANAGER_HOLDER.get().isMasterRouteOnly() : false;
}

/**
* 清理线索分片管理器的本地线程持有者.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import com.dangdang.ddframe.rdb.sharding.api.strategy.slave.RoundRobinSlaveLoadBalanceStrategy;
import com.dangdang.ddframe.rdb.sharding.api.strategy.slave.SlaveLoadBalanceStrategy;
import com.dangdang.ddframe.rdb.sharding.hint.HintManagerHolder;
import com.dangdang.ddframe.rdb.sharding.jdbc.adapter.AbstractDataSourceAdapter;
import com.dangdang.ddframe.rdb.sharding.parser.result.router.SQLStatementType;
import com.google.common.base.Preconditions;
Expand Down Expand Up @@ -60,7 +61,7 @@ protected Boolean initialValue() {
* @return 主或从节点的数据源
*/
public DataSource getDataSource(final SQLStatementType sqlStatementType) {
if (SQLStatementType.SELECT != sqlStatementType || WAS_UPDATED.get()) {
if (SQLStatementType.SELECT != sqlStatementType || WAS_UPDATED.get() || HintManagerHolder.isMasterRouteOnly()) {
WAS_UPDATED.set(true);
return masterDataSource;
}
Expand All @@ -70,7 +71,7 @@ public DataSource getDataSource(final SQLStatementType sqlStatementType) {
String getDatabaseProductName() throws SQLException {
String result;
try (Connection masterConnection = masterDataSource.getConnection()) {
result = masterConnection.getMetaData().getDatabaseProductName();
result = masterConnection.getMetaData().getDatabaseProductName();
}
for (DataSource each : slaveDataSources) {
String slaveDatabaseProductName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,18 @@ public void assertGetTableShardingValue() {
assertTrue(HintManagerHolder.getTableShardingValue(new ShardingKey("logicTable", "shardingColumn")).isPresent());
}

@Test
public void assertIsMasterRouteOnlyWithoutSet() {
hintManager.close();
assertFalse(HintManagerHolder.isMasterRouteOnly());
}

@Test
public void assertIsMasterRouteOnly() {
hintManager.setMasterRouteOnly();
assertTrue(HintManagerHolder.isMasterRouteOnly());
}

@Test
public void assertClear() {
hintManager.addDatabaseShardingValue("logicTable", "shardingColumn", 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package com.dangdang.ddframe.rdb.sharding.jdbc;

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.parser.result.router.SQLStatementType;
Expand Down Expand Up @@ -69,6 +70,14 @@ public void assertGetDataSourceForDMLAndDQL() {
assertThat(masterSlaveDataSource.getDataSource(SQLStatementType.SELECT), is(masterDataSource));
}

@Test
public void assertGetDataSourceForHintToMasterOnly() {
HintManager hintManager = HintManager.getInstance();
hintManager.setMasterRouteOnly();
assertThat(masterSlaveDataSource.getDataSource(SQLStatementType.SELECT), is(masterDataSource));
hintManager.close();
}

@Test(expected = IllegalStateException.class)
public void assertGetDatabaseProductNameWhenDataBaseProductNameDifferent() throws SQLException {
DataSource masterDataSource = mock(DataSource.class);
Expand Down
13 changes: 10 additions & 3 deletions sharding-jdbc-doc/content/post/master_slave.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@ weight = 6
## 支持项
1. 提供了一主多从的读写分离配置,可配合分库分表使用。
1. 同一线程如果有写入操作,以后的读操作均从主库读取,用于保证同一线程中的数据一致性。
1. Spring命名空间。
1. 基于Hint的强制主库路由。

## 待支持项
1. Spring命名空间
1. 基于Hint的强制主库读取配置

## 不支持范围
1. 主库和从库的数据同步。
Expand Down Expand Up @@ -111,3 +110,11 @@ dataSourceMap.put("ms_1", masterSlaveDs1);
</rdb:data-source>
</beans>
```

## 使用Hint强制路由主库示例

```java
HintManager hintManager = HintManager.getInstance();
hintManager.setMasterRouteOnly();
// 继续JDBC操作
```

0 comments on commit 5980c97

Please sign in to comment.