提交 76a65674 编写于 作者: T terrymanu

fix #95

上级 735744b4
......@@ -81,17 +81,6 @@ public final class HintManagerHolder {
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();
}
}
/**
* 清理线索分片管理器的本地线程持有者.
*/
......
......@@ -38,6 +38,14 @@ import java.util.List;
@RequiredArgsConstructor
public final class MasterSlaveDataSource extends AbstractDataSourceAdapter {
private static final ThreadLocal<Boolean> DML_FLAG = new ThreadLocal<Boolean>() {
@Override
protected Boolean initialValue() {
return false;
}
};
private final String name;
private final DataSource masterDataSource;
......@@ -53,8 +61,8 @@ public final class MasterSlaveDataSource extends AbstractDataSourceAdapter {
* @return 主或从节点的数据源
*/
public DataSource getDataSource(final SQLStatementType sqlStatementType) {
if (SQLStatementType.SELECT != sqlStatementType || HintManagerHolder.isMasterRouteOnly()) {
HintManagerHolder.setMasterRouteOnly();
if (SQLStatementType.SELECT != sqlStatementType || DML_FLAG.get() || HintManagerHolder.isMasterRouteOnly()) {
DML_FLAG.set(true);
return masterDataSource;
}
return slaveLoadBalanceStrategy.getDataSource(name, slaveDataSources);
......@@ -79,4 +87,11 @@ public final class MasterSlaveDataSource extends AbstractDataSourceAdapter {
public Connection getConnection() throws SQLException {
throw new UnsupportedOperationException("Master slave data source cannot support get connection directly.");
}
/**
* 重置更新标记.
*/
public static void resetDMLFlag() {
DML_FLAG.remove();
}
}
......@@ -18,6 +18,7 @@
package com.dangdang.ddframe.rdb.sharding.jdbc;
import com.codahale.metrics.Timer.Context;
import com.dangdang.ddframe.rdb.sharding.hint.HintManagerHolder;
import com.dangdang.ddframe.rdb.sharding.jdbc.adapter.AbstractConnectionAdapter;
import com.dangdang.ddframe.rdb.sharding.metrics.MetricsContext;
import com.dangdang.ddframe.rdb.sharding.parser.result.router.SQLStatementType;
......@@ -132,4 +133,11 @@ public final class ShardingConnection extends AbstractConnectionAdapter {
public Collection<Connection> getConnections() {
return connectionMap.values();
}
@Override
public void close() throws SQLException {
super.close();
HintManagerHolder.clear();
MasterSlaveDataSource.resetDMLFlag();
}
}
......@@ -17,15 +17,15 @@
package com.dangdang.ddframe.rdb.sharding.jdbc.adapter;
import com.dangdang.ddframe.rdb.sharding.jdbc.unsupported.AbstractUnsupportedOperationConnection;
import com.dangdang.ddframe.rdb.sharding.metrics.MetricsContext;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.util.Collection;
import com.dangdang.ddframe.rdb.sharding.jdbc.unsupported.AbstractUnsupportedOperationConnection;
import com.dangdang.ddframe.rdb.sharding.metrics.MetricsContext;
/**
* 数据库连接适配类.
*
......@@ -75,7 +75,7 @@ public abstract class AbstractConnectionAdapter extends AbstractUnsupportedOpera
}
@Override
public final void close() throws SQLException {
public void close() throws SQLException {
for (Connection each : getConnections()) {
each.close();
}
......
......@@ -47,6 +47,7 @@ public abstract class AbstractShardingMasterSlaveDBUnitTest extends AbstractDBUn
@After
public void reset() throws NoSuchFieldException, IllegalAccessException {
HintManagerHolder.clear();
MasterSlaveDataSource.resetDMLFlag();
}
@Override
......
......@@ -181,7 +181,7 @@ public final class ShardingMasterSlaveForPStatementWithDMLTest extends AbstractS
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
assertDataSet(String.format("integrate/dataset/masterslave/expect/%s/master_%s.xml", expectedDataSetPattern, i),
shardingDataSource.getConnection().getConnection(String.format("ms_%s", i), SQLStatementType.SELECT),
shardingDataSource.getConnection().getConnection(String.format("ms_%s", i), SQLStatementType.INSERT),
String.format("t_order_%s", j), String.format("SELECT * FROM `t_order_%s` WHERE `status`=?", j), status);
}
}
......
......@@ -84,7 +84,7 @@ public final class ShardingMasterSlaveForStatementWithDMLTest extends AbstractSh
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
assertDataSet(String.format("integrate/dataset/masterslave/expect/%s/master_%s.xml", expectedDataSetPattern, i),
shardingDataSource.getConnection().getConnection(String.format("ms_%s", i), SQLStatementType.SELECT),
shardingDataSource.getConnection().getConnection(String.format("ms_%s", i), SQLStatementType.INSERT),
String.format("t_order_%s", j), String.format("SELECT * FROM `t_order_%s` WHERE `status`=?", j), status);
}
}
......
......@@ -121,7 +121,7 @@ public final class PreparedStatementExecutorTest {
SQLException exp = new SQLException();
when(preparedStatement.executeQuery()).thenThrow(exp);
PreparedStatementExecutor actual = new PreparedStatementExecutor(executorEngine, Collections.singleton(wrapper));
assertThat(actual.executeQuery(), is(Collections.singletonList(((ResultSet) null))));
assertThat(actual.executeQuery(), is(Collections.singletonList((ResultSet) null)));
verify(preparedStatement).executeQuery();
verify(eventCaller, times(2)).verifyDataSource("ds_0");
verify(eventCaller, times(2)).verifySQL("SELECT * FROM dual");
......
......@@ -83,22 +83,6 @@ public final class HintManagerHolderTest {
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
public void assertClear() {
hintManager.addDatabaseShardingValue("logicTable", "shardingColumn", 1);
......
......@@ -50,6 +50,7 @@ public final class MasterSlaveDataSourceTest {
@After
public void reset() {
HintManagerHolder.clear();
MasterSlaveDataSource.resetDMLFlag();
}
@Test
......@@ -121,4 +122,12 @@ public final class MasterSlaveDataSourceTest {
public void assertGetConnection() throws SQLException {
masterSlaveDataSource.getConnection();
}
@Test
public void assertResetDMLFlag() {
assertThat(masterSlaveDataSource.getDataSource(SQLStatementType.INSERT), is(masterDataSource));
assertThat(masterSlaveDataSource.getDataSource(SQLStatementType.SELECT), is(masterDataSource));
MasterSlaveDataSource.resetDMLFlag();
assertThat(masterSlaveDataSource.getDataSource(SQLStatementType.SELECT), is(slaveDataSource));
}
}
......@@ -10,7 +10,7 @@ weight = 6
## 支持项
1. 提供了一主多从的读写分离配置,可配合分库分表使用。
1. 同一`HintManager`生命周期内,如有写入操作,以后的读操作均从主库读取,用于保证同一线程中的数据一致性。
1. 同一线程且同一数据库连接内,如有写入操作,以后的读操作均从主库读取,用于保证数据一致性。
1. `Spring`命名空间。
1. 基于`Hint`的强制主库路由。
......
......@@ -11,11 +11,12 @@ weight = 1
### 功能提升
1. [ISSUE #91](https://github.com/dangdangdotcom/sharding-jdbc/issues/91) 开放对Statement.getGeneratedKeys的支持,可返回原生的数据库自增主键
1. [ISSUE #91](https://github.com/dangdangdotcom/sharding-jdbc/issues/92) 查询类DQL语句事件发送
1. [ISSUE #92](https://github.com/dangdangdotcom/sharding-jdbc/issues/92) 查询类DQL语句事件发送
### 缺陷修正
1. [ISSUE #89](https://github.com/dangdangdotcom/sharding-jdbc/issues/89) 读写分离和分片的hint一起使用导致冲突
1. [ISSUE #95](https://github.com/dangdangdotcom/sharding-jdbc/issues/95) 同一线程内写入操作后的读操作均从主库读取改为同一线程且同一连接内
## 1.3.0
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册