共计 7405 个字符,预计需要花费 19 分钟才能阅读完成。
序
本文主要研究一下 sharding-jdbc 的 SingleXADataSource
SingleXADataSource
incubator-shardingsphere-4.0.0-RC1/sharding-transaction/sharding-transaction-2pc/sharding-transaction-xa/sharding-transaction-xa-core/src/main/java/org/apache/shardingsphere/transaction/xa/jta/datasource/SingleXADataSource.java
public final class SingleXADataSource extends AbstractUnsupportedSingleXADataSource {
@Getter
private final String resourceName;
@Getter
private final XADataSource xaDataSource;
private final DatabaseType databaseType;
private final DataSource originalDataSource;
private final boolean isOriginalXADataSource;
public SingleXADataSource(final DatabaseType databaseType, final String resourceName, final DataSource dataSource) {
this.databaseType = databaseType;
this.resourceName = resourceName;
originalDataSource = dataSource;
if (dataSource instanceof XADataSource) {xaDataSource = (XADataSource) dataSource;
isOriginalXADataSource = true;
} else {xaDataSource = XADataSourceFactory.build(databaseType, dataSource);
isOriginalXADataSource = false;
}
}
@Override
public SingleXAConnection getXAConnection() throws SQLException {return isOriginalXADataSource ? getXAConnectionFromXADataSource() : getXAConnectionFromNoneXADataSource();}
private SingleXAConnection getXAConnectionFromXADataSource() throws SQLException {XAConnection xaConnection = xaDataSource.getXAConnection();
return new SingleXAConnection(resourceName, xaConnection.getConnection(), xaConnection);
}
private SingleXAConnection getXAConnectionFromNoneXADataSource() throws SQLException {Connection originalConnection = originalDataSource.getConnection();
XAConnection xaConnection = XAConnectionFactory.createXAConnection(databaseType, xaDataSource, originalConnection);
return new SingleXAConnection(resourceName, originalConnection, xaConnection);
}
}
- SingleXADataSource 继承了 AbstractUnsupportedSingleXADataSource,其 getXAConnection 方法会根据 isOriginalXADataSource 来选择是 getXAConnectionFromXADataSource 还是 getXAConnectionFromNoneXADataSource
AbstractUnsupportedSingleXADataSource
incubator-shardingsphere-4.0.0-RC1/sharding-transaction/sharding-transaction-2pc/sharding-transaction-xa/sharding-transaction-xa-core/src/main/java/org/apache/shardingsphere/transaction/xa/jta/datasource/AbstractUnsupportedSingleXADataSource.java
public abstract class AbstractUnsupportedSingleXADataSource implements XADataSource {
@Override
public final XAConnection getXAConnection(final String user, final String password) throws SQLException {throw new SQLFeatureNotSupportedException("getXAConnection by user and password");
}
@Override
public final PrintWriter getLogWriter() throws SQLException {throw new SQLFeatureNotSupportedException("getLogWriter");
}
@Override
public final void setLogWriter(final PrintWriter out) throws SQLException {throw new SQLFeatureNotSupportedException("setLogWriter");
}
@Override
public final void setLoginTimeout(final int seconds) throws SQLException {throw new SQLFeatureNotSupportedException("setLoginTimeout");
}
@Override
public final int getLoginTimeout() throws SQLException {throw new SQLFeatureNotSupportedException("getLoginTimeout");
}
@Override
public final Logger getParentLogger() throws SQLFeatureNotSupportedException {throw new SQLFeatureNotSupportedException("getParentLogger");
}
}
- AbstractUnsupportedSingleXADataSource 声明实现 java.sql.XADataSource 接口,对于 getXAConnection、getLogWriter、setLogWriter、setLoginTimeout、getLoginTimeout、getParentLogger 方法抛出 SQLFeatureNotSupportedException
SingleXADataSourceTest
incubator-shardingsphere-4.0.0-RC1/sharding-transaction/sharding-transaction-2pc/sharding-transaction-xa/sharding-transaction-xa-core/src/test/java/org/apache/shardingsphere/transaction/xa/jta/datasource/SingleXADataSourceTest.java
public final class SingleXADataSourceTest {
@Test
public void assertBuildSingleXADataSourceOfXA() {DataSource dataSource = DataSourceUtils.build(DruidXADataSource.class, DatabaseType.MySQL, "ds1");
SingleXADataSource actual = new SingleXADataSource(DatabaseType.MySQL, "ds1", dataSource);
assertThat(actual.getResourceName(), is("ds1"));
assertThat(actual.getXaDataSource(), is((XADataSource) dataSource));
}
@Test
public void assertBuildSingleXADataSourceOfNoneXA() {DataSource dataSource = DataSourceUtils.build(HikariDataSource.class, DatabaseType.H2, "ds1");
SingleXADataSource actual = new SingleXADataSource(DatabaseType.H2, "ds1", dataSource);
assertThat(actual.getResourceName(), is("ds1"));
assertThat(actual.getXaDataSource(), instanceOf(JdbcDataSource.class));
JdbcDataSource jdbcDataSource = (JdbcDataSource) actual.getXaDataSource();
assertThat(jdbcDataSource.getUser(), is("root"));
assertThat(jdbcDataSource.getPassword(), is("root"));
}
@Test
@SneakyThrows
public void assertGetXAConnectionOfXA() {DataSource dataSource = DataSourceUtils.build(DruidXADataSource.class, DatabaseType.H2, "ds1");
SingleXADataSource shardingXADataSource = new SingleXADataSource(DatabaseType.H2, "ds1", dataSource);
SingleXAConnection actual = shardingXADataSource.getXAConnection();
assertThat(actual.getConnection(), instanceOf(Connection.class));
}
@Test
@SneakyThrows
public void assertGetXAConnectionOfNoneXA() {DataSource dataSource = DataSourceUtils.build(HikariDataSource.class, DatabaseType.H2, "ds1");
SingleXADataSource shardingXADataSource = new SingleXADataSource(DatabaseType.H2, "ds1", dataSource);
SingleXAConnection actual = shardingXADataSource.getXAConnection();
assertThat(actual.getConnection(), instanceOf(Connection.class));
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void assertGetLoginTimeout() throws SQLException {DataSource dataSource = DataSourceUtils.build(DruidXADataSource.class, DatabaseType.H2, "ds1");
SingleXADataSource shardingXADataSource = new SingleXADataSource(DatabaseType.H2, "ds1", dataSource);
shardingXADataSource.getLoginTimeout();}
@Test(expected = SQLFeatureNotSupportedException.class)
public void assertSetLogWriter() throws SQLException {DataSource dataSource = DataSourceUtils.build(DruidXADataSource.class, DatabaseType.H2, "ds1");
SingleXADataSource shardingXADataSource = new SingleXADataSource(DatabaseType.H2, "ds1", dataSource);
shardingXADataSource.setLogWriter(null);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void assertSetLoginTimeout() throws SQLException {DataSource dataSource = DataSourceUtils.build(DruidXADataSource.class, DatabaseType.H2, "ds1");
SingleXADataSource shardingXADataSource = new SingleXADataSource(DatabaseType.H2, "ds1", dataSource);
shardingXADataSource.setLoginTimeout(10);
}
@Test(expected = SQLFeatureNotSupportedException.class)
public void assertGetParentLogger() throws SQLException {DataSource dataSource = DataSourceUtils.build(DruidXADataSource.class, DatabaseType.H2, "ds1");
SingleXADataSource shardingXADataSource = new SingleXADataSource(DatabaseType.H2, "ds1", dataSource);
shardingXADataSource.getParentLogger();}
@Test(expected = SQLFeatureNotSupportedException.class)
public void assertGetLogWriter() throws SQLException {DataSource dataSource = DataSourceUtils.build(DruidXADataSource.class, DatabaseType.H2, "ds1");
SingleXADataSource shardingXADataSource = new SingleXADataSource(DatabaseType.H2, "ds1", dataSource);
shardingXADataSource.getLogWriter();}
@Test(expected = SQLFeatureNotSupportedException.class)
public void assertGetXAConnectionByUserAndPassword() throws SQLException {DataSource dataSource = DataSourceUtils.build(DruidXADataSource.class, DatabaseType.H2, "ds1");
SingleXADataSource shardingXADataSource = new SingleXADataSource(DatabaseType.H2, "ds1", dataSource);
shardingXADataSource.getXAConnection("root", "root");
}
}
- SingleXADataSourceTest 验证了 XADataSource 的构建、获取 XAConnection 以及其他一些不支持的方法
小结
SingleXADataSource 继承了 AbstractUnsupportedSingleXADataSource,其 getXAConnection 方法会根据 isOriginalXADataSource 来选择是 getXAConnectionFromXADataSource 还是 getXAConnectionFromNoneXADataSource
doc
- SingleXADataSource