Java源码示例:org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy

示例1
public ReplicationRoutingDataSource(DataSource master, List<DataSource> slaves) {

		Assert.notNull(master, "master datasource can not be null.");

		Map<Object, Object> targetDataSources = new HashMap<>();
		targetDataSources.put(MASTER_KEY, new LazyConnectionDataSourceProxy(master));
		if (!CollectionUtils.isEmpty(slaves)) {
			slaveSize = slaves.size();
			for (int i = 0; i < slaveSize; i++) {
				targetDataSources.put(SLAVE_PREFIX + i,
						new LazyConnectionDataSourceProxy(slaves.get(i)));
			}
		}
		else {
			this.onlyMaster = true;
		}
		setTargetDataSources(targetDataSources);
		setDefaultTargetDataSource(targetDataSources.get(MASTER_KEY));
	}
 
示例2
@Override
public void afterPropertiesSet() throws Exception {
	if (this.shardsDataSources == null) {
		throw new IllegalArgumentException("Property 'shardsDataSources' is required");
	}
	this.resolvedShardsDataSources = new HashMap<Object, DataSource>(this.shardsDataSources.size());
	for (Map.Entry<Object, Object> entry : this.shardsDataSources.entrySet()) {
		DataSource dataSource = resolveSpecifiedDataSource(entry.getValue());
		LazyConnectionDataSourceProxy lazyDataSourceProxy = new LazyConnectionDataSourceProxy();
		lazyDataSourceProxy.setTargetDataSource(dataSource);
		this.resolvedShardsDataSources.put(entry.getKey(), lazyDataSourceProxy);
	}
	if (this.defaultDataSource == null) {
		throw new IllegalArgumentException("Property 'defaultDataSource' is required");
	}
	if(this.defaultDataSource != null){
		resolvedDefaultDataSource = this.resolveSpecifiedDataSource(defaultDataSource);
	}
	
}
 
示例3
@Override
protected void destroyInstance(DataSource instance) throws Exception {
	if (instance instanceof LazyConnectionDataSourceProxy) {
		DataSource targetDataSource = ((LazyConnectionDataSourceProxy) instance)
				.getTargetDataSource();
		if (targetDataSource instanceof ReadOnlyRoutingDataSource) {
			List<Object> dataSources = ((ReadOnlyRoutingDataSource) targetDataSource)
					.getDataSources();
			for (Object candidate : dataSources) {
				if (candidate instanceof DataSource) {
					super.destroyInstance(instance);
				}
			}
		}
	}
}
 
示例4
@Test
void getConnection_NoReadReplicaAvailableNoTransactionActive_returnsDefaultDataSource()
		throws Exception {

	// Arrange
	DataSource defaultDataSource = mock(DataSource.class);
	Connection connection = mock(Connection.class);

	when(defaultDataSource.getConnection()).thenReturn(connection);

	ReadOnlyRoutingDataSource readOnlyRoutingDataSource = new ReadOnlyRoutingDataSource();
	readOnlyRoutingDataSource.setTargetDataSources(Collections.emptyMap());
	readOnlyRoutingDataSource.setDefaultTargetDataSource(defaultDataSource);
	readOnlyRoutingDataSource.afterPropertiesSet();

	LazyConnectionDataSourceProxy dataSource = new LazyConnectionDataSourceProxy(
			readOnlyRoutingDataSource);

	// Act
	Connection connectionReturned = dataSource.getConnection();

	// Assert
	assertThat(((ConnectionProxy) connectionReturned).getTargetConnection())
			.isSameAs(connection);
}
 
示例5
/**
 * Constructs a
 * {@link org.springframework.cloud.aws.jdbc.datasource.ReadOnlyRoutingDataSource}
 * data source that contains the regular data source as a default, and all
 * read-replicas as additional data source. The
 * {@link org.springframework.cloud.aws.jdbc.datasource.ReadOnlyRoutingDataSource} is
 * additionally wrapped with a
 * {@link org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy}, because
 * the read-only flag is only available after the transactional context has been
 * established. This is only the case if the physical connection is requested after
 * the transaction start and not while starting a transaction.
 * @return a ReadOnlyRoutingDataSource that is wrapped with a
 * LazyConnectionDataSourceProxy
 * @throws Exception if the underlying data source setup throws any exception
 */
@Override
protected DataSource createInstance() throws Exception {
	DBInstance dbInstance = getDbInstance(getDbInstanceIdentifier());

	// If there is no read replica available, delegate to super class
	if (dbInstance.getReadReplicaDBInstanceIdentifiers().isEmpty()) {
		return super.createInstance();
	}

	HashMap<Object, Object> replicaMap = new HashMap<>(
			dbInstance.getReadReplicaDBInstanceIdentifiers().size());

	for (String replicaName : dbInstance.getReadReplicaDBInstanceIdentifiers()) {
		replicaMap.put(replicaName, createDataSourceInstance(replicaName));
	}

	// Create the data source
	ReadOnlyRoutingDataSource dataSource = new ReadOnlyRoutingDataSource();
	dataSource.setTargetDataSources(replicaMap);
	dataSource.setDefaultTargetDataSource(
			createDataSourceInstance(getDbInstanceIdentifier()));

	// Initialize the class
	dataSource.afterPropertiesSet();

	return new LazyConnectionDataSourceProxy(dataSource);
}
 
示例6
@Test
void getConnection_NoReadReplicaAvailableReadOnlyTransactionActive_returnsDefaultDataSource()
		throws Exception {

	// Arrange
	DataSource defaultDataSource = mock(DataSource.class);
	Connection connection = mock(Connection.class);

	when(defaultDataSource.getConnection()).thenReturn(connection);

	ReadOnlyRoutingDataSource readOnlyRoutingDataSource = new ReadOnlyRoutingDataSource();
	readOnlyRoutingDataSource.setTargetDataSources(Collections.emptyMap());
	readOnlyRoutingDataSource.setDefaultTargetDataSource(defaultDataSource);
	readOnlyRoutingDataSource.afterPropertiesSet();

	LazyConnectionDataSourceProxy dataSource = new LazyConnectionDataSourceProxy(
			readOnlyRoutingDataSource);

	DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
	transactionDefinition.setReadOnly(true);

	TransactionTemplate transactionTemplate = new TransactionTemplate(
			new DataSourceTransactionManager(dataSource), transactionDefinition);

	// Act
	Connection connectionReturned = transactionTemplate.execute(status -> {
		try {
			return ((ConnectionProxy) dataSource.getConnection())
					.getTargetConnection();
		}
		catch (SQLException e) {
			fail(e.getMessage());
		}
		return null;
	});

	// Assert
	assertThat(connectionReturned).isSameAs(connection);
}
 
示例7
public void afterPropertiesSet() throws Exception {
    if (getHaDataSourceCreator() == null) {
        setHaDataSourceCreator(new NonHADataSourceCreator());
    }
    if (CollectionUtils.isEmpty(dataSourceDescriptors)) {
        return;
    }

    for (CobarDataSourceDescriptor descriptor : getDataSourceDescriptors()) {
        Validate.notEmpty(descriptor.getIdentity());
        Validate.notNull(descriptor.getTargetDataSource());

        DataSource dataSourceToUse = descriptor.getTargetDataSource();

        if (descriptor.getStandbyDataSource() != null) {
            dataSourceToUse = getHaDataSourceCreator().createHADataSource(descriptor);
            if (CollectionUtils.isNotEmpty(dataSourcePostProcessor)) {
                for (IDataSourcePostProcessor pp : dataSourcePostProcessor) {
                    dataSourceToUse = pp.postProcess(dataSourceToUse);
                }
            }
        }

        dataSources.put(descriptor.getIdentity(), new LazyConnectionDataSourceProxy(
                dataSourceToUse));
    }
}
 
示例8
@Test
public void testTransactionCommitWithNonExistingDatabaseAndLazyConnection() throws Exception {
	DriverManagerDataSource dsTarget = new DriverManagerDataSource();
	final LazyConnectionDataSourceProxy ds = new LazyConnectionDataSourceProxy();
	ds.setTargetDataSource(dsTarget);
	ds.setDefaultAutoCommit(true);
	ds.setDefaultTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
	//ds.setDefaultTransactionIsolationName("TRANSACTION_READ_COMMITTED");

	LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean();
	lsfb.setDataSource(ds);
	Properties props = new Properties();
	props.setProperty("hibernate.dialect", HSQLDialect.class.getName());
	props.setProperty("hibernate.cache.provider_class", NoCacheProvider.class.getName());
	props.setProperty("hibernate.temp.use_jdbc_metadata_defaults", "false");
	lsfb.setHibernateProperties(props);
	lsfb.afterPropertiesSet();
	final SessionFactory sf = lsfb.getObject();

	HibernateTransactionManager tm = new HibernateTransactionManager();
	tm.setSessionFactory(sf);
	tm.afterPropertiesSet();
	TransactionTemplate tt = new TransactionTemplate(tm);
	tt.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE);
	tt.setTimeout(10);
	assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf));
	assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds));
	assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive());

	tt.execute(new TransactionCallback() {
		@Override
		public Object doInTransaction(TransactionStatus status) {
			assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf));
			assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds));
			HibernateTemplate ht = new HibernateTemplate(sf);
			return ht.find("from java.lang.Object");
		}
	});

	assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf));
	assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds));
	assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive());
}
 
示例9
@Test
public void testTransactionCommitWithNonExistingDatabaseAndLazyConnection() throws Exception {
	DriverManagerDataSource dsTarget = new DriverManagerDataSource();
	final LazyConnectionDataSourceProxy ds = new LazyConnectionDataSourceProxy();
	ds.setTargetDataSource(dsTarget);
	ds.setDefaultAutoCommit(true);
	ds.setDefaultTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
	//ds.setDefaultTransactionIsolationName("TRANSACTION_READ_COMMITTED");

	LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean();
	lsfb.setDataSource(ds);
	Properties props = new Properties();
	props.setProperty("hibernate.dialect", HSQLDialect.class.getName());
	props.setProperty("hibernate.temp.use_jdbc_metadata_defaults", "false");
	lsfb.setHibernateProperties(props);
	lsfb.afterPropertiesSet();
	final SessionFactory sf = lsfb.getObject();

	HibernateTransactionManager tm = new HibernateTransactionManager();
	tm.setSessionFactory(sf);
	tm.afterPropertiesSet();
	TransactionTemplate tt = new TransactionTemplate(tm);
	tt.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE);
	tt.setTimeout(10);
	assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf));
	assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds));
	assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive());

	tt.execute(new TransactionCallback() {
		@Override
		public Object doInTransaction(TransactionStatus status) {
			assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf));
			assertTrue("Has thread connection", TransactionSynchronizationManager.hasResource(ds));
			Session session = ((SessionHolder) TransactionSynchronizationManager.getResource(sf)).getSession();
			return session.createQuery("from java.lang.Object").list();
		}
	});

	assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf));
	assertTrue("Hasn't thread connection", !TransactionSynchronizationManager.hasResource(ds));
	assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive());
}
 
示例10
@Test
void getConnection_ReadReplicaAvailableReadOnlyTransactionActive_returnsReadReplicaDataSource()
		throws Exception {

	// Arrange
	DataSource defaultDataSource = mock(DataSource.class);
	Connection connection = mock(Connection.class);

	DataSource readOnlyDataSource = mock(DataSource.class);
	Connection readOnlyConnection = mock(Connection.class);

	when(readOnlyDataSource.getConnection()).thenReturn(readOnlyConnection);
	when(defaultDataSource.getConnection()).thenReturn(connection);

	ReadOnlyRoutingDataSource readOnlyRoutingDataSource = new ReadOnlyRoutingDataSource();
	readOnlyRoutingDataSource.setTargetDataSources(
			Collections.singletonMap("read1", readOnlyDataSource));
	readOnlyRoutingDataSource.setDefaultTargetDataSource(defaultDataSource);
	readOnlyRoutingDataSource.afterPropertiesSet();

	LazyConnectionDataSourceProxy dataSource = new LazyConnectionDataSourceProxy(
			readOnlyRoutingDataSource);

	DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
	transactionDefinition.setReadOnly(true);

	TransactionTemplate transactionTemplate = new TransactionTemplate(
			new DataSourceTransactionManager(dataSource), transactionDefinition);

	// Act
	Connection connectionReturned = transactionTemplate.execute(status -> {
		try {
			return ((ConnectionProxy) dataSource.getConnection())
					.getTargetConnection();
		}
		catch (SQLException e) {
			fail(e.getMessage());
		}
		return null;
	});

	// Assert
	assertThat(connectionReturned).isSameAs(readOnlyConnection);
}
 
示例11
@Test
void getConnection_ReadReplicaAvailableWriteTransactionActive_returnsDefaultDataSource()
		throws Exception {

	// Arrange
	DataSource defaultDataSource = mock(DataSource.class);
	Connection connection = mock(Connection.class);

	DataSource readOnlyDataSource = mock(DataSource.class);
	Connection readOnlyConnection = mock(Connection.class);

	when(readOnlyDataSource.getConnection()).thenReturn(readOnlyConnection);
	when(defaultDataSource.getConnection()).thenReturn(connection);

	ReadOnlyRoutingDataSource readOnlyRoutingDataSource = new ReadOnlyRoutingDataSource();
	readOnlyRoutingDataSource.setTargetDataSources(
			Collections.singletonMap("read1", readOnlyDataSource));
	readOnlyRoutingDataSource.setDefaultTargetDataSource(defaultDataSource);
	readOnlyRoutingDataSource.afterPropertiesSet();

	LazyConnectionDataSourceProxy dataSource = new LazyConnectionDataSourceProxy(
			readOnlyRoutingDataSource);

	DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
	transactionDefinition.setReadOnly(false);

	TransactionTemplate transactionTemplate = new TransactionTemplate(
			new DataSourceTransactionManager(dataSource), transactionDefinition);

	// Act
	Connection connectionReturned = transactionTemplate.execute(status -> {
		try {
			return ((ConnectionProxy) dataSource.getConnection())
					.getTargetConnection();
		}
		catch (SQLException e) {
			fail(e.getMessage());
		}
		return null;
	});

	// Assert
	assertThat(connectionReturned).isSameAs(connection);
}
 
示例12
@Test
void afterPropertiesSet_instanceWithReadReplica_createsDataSourceRouter()
		throws Exception {
	// Arrange
	AmazonRDS amazonRDS = mock(AmazonRDS.class);
	DataSourceFactory dataSourceFactory = mock(DataSourceFactory.class);

	when(amazonRDS.describeDBInstances(
			new DescribeDBInstancesRequest().withDBInstanceIdentifier("test")))
					.thenReturn(new DescribeDBInstancesResult().withDBInstances(
							new DBInstance().withDBInstanceStatus("available")
									.withDBName("test")
									.withDBInstanceIdentifier("test")
									.withEngine("mysql").withMasterUsername("admin")
									.withEndpoint(new Endpoint()
											.withAddress("localhost").withPort(3306))
									.withReadReplicaDBInstanceIdentifiers("read1",
											"read2")));

	when(amazonRDS.describeDBInstances(new DescribeDBInstancesRequest()
			.withDBInstanceIdentifier("read1"))).thenReturn(
					new DescribeDBInstancesResult().withDBInstances(new DBInstance()
							.withDBInstanceStatus("available").withDBName("read1")
							.withDBInstanceIdentifier("read1").withEngine("mysql")
							.withMasterUsername("admin").withEndpoint(new Endpoint()
									.withAddress("localhost").withPort(3306))));

	when(amazonRDS.describeDBInstances(new DescribeDBInstancesRequest()
			.withDBInstanceIdentifier("read2"))).thenReturn(
					new DescribeDBInstancesResult().withDBInstances(new DBInstance()
							.withDBInstanceStatus("available").withDBName("read2")
							.withDBInstanceIdentifier("read2").withEngine("mysql")
							.withMasterUsername("admin").withEndpoint(new Endpoint()
									.withAddress("localhost").withPort(3306))));

	DataSource createdDataSource = mock(DataSource.class);
	Connection connection = mock(Connection.class);

	when(dataSourceFactory.createDataSource(new DataSourceInformation(
			DatabaseType.MYSQL, "localhost", 3306, "test", "admin", "secret")))
					.thenReturn(createdDataSource);
	when(dataSourceFactory.createDataSource(new DataSourceInformation(
			DatabaseType.MYSQL, "localhost", 3306, "read1", "admin", "secret")))
					.thenReturn(createdDataSource);
	when(dataSourceFactory.createDataSource(new DataSourceInformation(
			DatabaseType.MYSQL, "localhost", 3306, "read2", "admin", "secret")))
					.thenReturn(createdDataSource);
	when(createdDataSource.getConnection()).thenReturn(connection);

	AmazonRdsReadReplicaAwareDataSourceFactoryBean factoryBean = new AmazonRdsReadReplicaAwareDataSourceFactoryBean(
			amazonRDS, "test", "secret");
	factoryBean.setDataSourceFactory(dataSourceFactory);

	// Act
	factoryBean.afterPropertiesSet();

	// Assert
	DataSource datasource = factoryBean.getObject();
	assertThat(datasource).isNotNull();
	assertThat(datasource instanceof LazyConnectionDataSourceProxy).isTrue();

	ReadOnlyRoutingDataSource source = (ReadOnlyRoutingDataSource) ((LazyConnectionDataSourceProxy) datasource)
			.getTargetDataSource();
	assertThat(source.getDataSources().size()).isEqualTo(3);
}
 
示例13
/**
 * {@link org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy}로 감싸서
 * 트랜잭션 동기화가 이루어진 뒤에 실제 커넥션을 확보하도록 해준다.
 *
 * @param routingDataSource
 * @return
 */
@Bean
public DataSource dataSource(@Qualifier("routingDataSource") DataSource routingDataSource) {
    return new LazyConnectionDataSourceProxy(routingDataSource);
}
 
示例14
/**
 * {@link org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy}로 감싸서
 * 트랜잭션 동기화가 이루어진 뒤에 실제 커넥션을 확보하도록 해준다.
 *
 * @param routingDataSource
 * @return
 */
@Bean
public DataSource dataSource(@Qualifier("routingDataSource") DataSource routingDataSource) {
    return new LazyConnectionDataSourceProxy(routingDataSource);
}