Skip to content

Conversation

sergiyvamz
Copy link
Contributor

Summary

docs: internal connection pool for Spring apps

Additional Reviewers

@karenc-bq
@crystall-bitquill
@aaronchung-bitquill

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@sergiyvamz sergiyvamz changed the title [WIP] docs: internal connection pool for Spring apps docs: internal connection pool for Spring apps Feb 2, 2024

When a method with this annotation is hit, Spring calls conn.setReadOnly(true), executes the method, and then calls setReadOnly(false) to restore the connection's initial readOnly value. Consequently, every time the method is called, the plugin switches to the reader, executes the method, and then switches back to the writer. Although the reader connection will be cached after the first setReadOnly call, there is still some overhead when switching between the cached writer/reader connections. This constant switching is not an ideal use of the plugin because it is frequently incurring this overhead. The suggested approach for this scenario is to avoid loading the read/write splitting plugin and instead use the writer cluster URL for your write operations and the reader cluster URL for your read operations. By doing this you avoid the overhead of constantly switching between connections while still spreading load across the database instances in your cluster.

#### Internal connection pools

We recommend that you do not enable internal connection pools when using Spring. This is because Spring by default uses its own external connection pool. The use of both internal and external pools is not tested and may result in problematic behavior.
We recommend that you do not enable internal connection pools when using Spring with default datasource configuration. This is because Spring by default uses its own external connection pool. The use of both internal and external pools is not tested and may result in problematic behavior. A Spring application should enable internal connection pool only. That's a recommended configuration.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add a link for default deatasource configuration? Not exactly sure what the default configuration is

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I rewrote this part. I hope it's a bit cleaner now.


When a method with this annotation is hit, Spring calls conn.setReadOnly(true), executes the method, and then calls setReadOnly(false) to restore the connection's initial readOnly value. Consequently, every time the method is called, the plugin switches to the reader, executes the method, and then switches back to the writer. Although the reader connection will be cached after the first setReadOnly call, there is still some overhead when switching between the cached writer/reader connections. This constant switching is not an ideal use of the plugin because it is frequently incurring this overhead. The suggested approach for this scenario is to avoid loading the read/write splitting plugin and instead use the writer cluster URL for your write operations and the reader cluster URL for your read operations. By doing this you avoid the overhead of constantly switching between connections while still spreading load across the database instances in your cluster.

#### Internal connection pools

We recommend that you do not enable internal connection pools when using Spring. This is because Spring by default uses its own external connection pool. The use of both internal and external pools is not tested and may result in problematic behavior.
We recommend that you do not enable internal connection pools when using Spring with default datasource configuration. This is because Spring by default uses its own external connection pool. The use of both internal and external pools is not tested and may result in problematic behavior. A Spring application should enable internal connection pool only. That's a recommended configuration.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
We recommend that you do not enable internal connection pools when using Spring with default datasource configuration. This is because Spring by default uses its own external connection pool. The use of both internal and external pools is not tested and may result in problematic behavior. A Spring application should enable internal connection pool only. That's a recommended configuration.
We recommend that you **disable** internal connection pools when using Spring with default datasource configuration. Spring by default uses its own external connection pool. The use of both internal and external pools has not been tested and may result in problematic behaviour. A Spring application should enable internal connection pool only. That's a recommended configuration.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand the last sentence. A Spring application should enable internal connection pool only. That's a recommended configuration. but the first sentence said to not use internal connection pool when using Spring with default datasource configuration.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I rewrote this part. I hope it's a bit cleaner now.

## Example
[ReadWriteSplittingPostgresExample.java](../../../examples/AWSDriverExample/src/main/java/software/amazon/ReadWriteSplittingPostgresExample.java) demonstrates how to enable and configure read/write splitting with the Aws Advanced JDBC Driver.

[SpringHibernateBalancedReaderOneDataSourceExample](../../../examples/SpringHibernateBalancedReaderOneDataSourceExample/README.md) demonstrates how to enable and configure read/write splitting with the Aws Advanced JDBC Driver. This example application uses a configuration with internal connection pool and provides a load-balanced reader connection according to a specified reader selection strategy. `Read/Write Splitting Plugin` and `@Transactional(readOnly = True)` play in collaboration in this example.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
[SpringHibernateBalancedReaderOneDataSourceExample](../../../examples/SpringHibernateBalancedReaderOneDataSourceExample/README.md) demonstrates how to enable and configure read/write splitting with the Aws Advanced JDBC Driver. This example application uses a configuration with internal connection pool and provides a load-balanced reader connection according to a specified reader selection strategy. `Read/Write Splitting Plugin` and `@Transactional(readOnly = True)` play in collaboration in this example.
[SpringHibernateBalancedReaderOneDataSourceExample](../../../examples/SpringHibernateBalancedReaderOneDataSourceExample/README.md) demonstrates how to enable and configure Read/Write Splitting plugin with the AWS JDBC Driver. This example application uses a configuration with internal connection pool and provides a load-balanced reader connection according to a specified reader selection strategy. `Read/Write Splitting Plugin` and `@Transactional(readOnly = True)` play in collaboration in this example.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding on top of Karen's suggestion:

Suggested change
[SpringHibernateBalancedReaderOneDataSourceExample](../../../examples/SpringHibernateBalancedReaderOneDataSourceExample/README.md) demonstrates how to enable and configure read/write splitting with the Aws Advanced JDBC Driver. This example application uses a configuration with internal connection pool and provides a load-balanced reader connection according to a specified reader selection strategy. `Read/Write Splitting Plugin` and `@Transactional(readOnly = True)` play in collaboration in this example.
[SpringHibernateBalancedReaderOneDataSourceExample](../../../examples/SpringHibernateBalancedReaderOneDataSourceExample/README.md) demonstrates how to enable and configure the Read/Write Splitting plugin with the AWS JDBC Driver. This example application uses a configuration with internal connection pooling and provides a load-balanced reader connection according to a specified reader selection strategy. The `Read/Write Splitting Plugin` and `@Transactional(readOnly = True)` annotation are both used in this example.

I'm not entirely sure what the last sentence means, does this sound right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've changed this sentence. Please take a look.

## Example
[ReadWriteSplittingPostgresExample.java](../../../examples/AWSDriverExample/src/main/java/software/amazon/ReadWriteSplittingPostgresExample.java) demonstrates how to enable and configure read/write splitting with the Aws Advanced JDBC Driver.

[SpringHibernateBalancedReaderOneDataSourceExample](../../../examples/SpringHibernateBalancedReaderOneDataSourceExample/README.md) demonstrates how to enable and configure read/write splitting with the Aws Advanced JDBC Driver. This example application uses a configuration with internal connection pool and provides a load-balanced reader connection according to a specified reader selection strategy. `Read/Write Splitting Plugin` and `@Transactional(readOnly = True)` play in collaboration in this example.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding on top of Karen's suggestion:

Suggested change
[SpringHibernateBalancedReaderOneDataSourceExample](../../../examples/SpringHibernateBalancedReaderOneDataSourceExample/README.md) demonstrates how to enable and configure read/write splitting with the Aws Advanced JDBC Driver. This example application uses a configuration with internal connection pool and provides a load-balanced reader connection according to a specified reader selection strategy. `Read/Write Splitting Plugin` and `@Transactional(readOnly = True)` play in collaboration in this example.
[SpringHibernateBalancedReaderOneDataSourceExample](../../../examples/SpringHibernateBalancedReaderOneDataSourceExample/README.md) demonstrates how to enable and configure the Read/Write Splitting plugin with the AWS JDBC Driver. This example application uses a configuration with internal connection pooling and provides a load-balanced reader connection according to a specified reader selection strategy. The `Read/Write Splitting Plugin` and `@Transactional(readOnly = True)` annotation are both used in this example.

I'm not entirely sure what the last sentence means, does this sound right?


When a method with this annotation is hit, Spring calls conn.setReadOnly(true), executes the method, and then calls setReadOnly(false) to restore the connection's initial readOnly value. Consequently, every time the method is called, the plugin switches to the reader, executes the method, and then switches back to the writer. Although the reader connection will be cached after the first setReadOnly call, there is still some overhead when switching between the cached writer/reader connections. This constant switching is not an ideal use of the plugin because it is frequently incurring this overhead. The suggested approach for this scenario is to avoid loading the read/write splitting plugin and instead use the writer cluster URL for your write operations and the reader cluster URL for your read operations. By doing this you avoid the overhead of constantly switching between connections while still spreading load across the database instances in your cluster.

#### Internal connection pools

We recommend that you do not enable internal connection pools when using Spring. This is because Spring by default uses its own external connection pool. The use of both internal and external pools is not tested and may result in problematic behavior.
We recommend that you explicitly disable internal connection pools when using Spring. You can check `spring.datasource.type` property to ensure that an external connection pooling is disabled. By default, Spring uses datasource auto-detection, and it may enable external connection pool. The use of both internal and external pools has not been tested and may result in problematic behaviour. A Spring application should enable internal connection pool only. That's a recommended configuration.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this paragraph mean that internal connection pooling isn't recommended to use, but if they are used, users should disable Spring's external connection pooling? And that both internal and external connection pooling shouldn't be used together? If that's the case, how does this sound:

Suggested change
We recommend that you explicitly disable internal connection pools when using Spring. You can check `spring.datasource.type` property to ensure that an external connection pooling is disabled. By default, Spring uses datasource auto-detection, and it may enable external connection pool. The use of both internal and external pools has not been tested and may result in problematic behaviour. A Spring application should enable internal connection pool only. That's a recommended configuration.
We recommend that you explicitly disable internal connection pools when using Spring. However, if you do use the driver's internal connection pooling, you can check the `spring.datasource.type` property to ensure that any external connection pooling is disabled. This is necessary because Spring uses datasource auto-detection by default, and it may enable external connection pooling. Using internal and external pools at the same time has not been tested and may result in problematic behaviour. The recommended configuration for a Spring application should either enable internal connection pooling or external connection pooling, but not both at once.

@sergiyvamz sergiyvamz merged commit aba7e6b into main Feb 6, 2024
@sergiyvamz sergiyvamz deleted the rw-splitting-doc branch February 6, 2024 21:08
Copy link
Contributor

@joyc-bq joyc-bq left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

jasonli-improving pushed a commit to Bit-Quill/aws-advanced-jdbc-wrapper that referenced this pull request Feb 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants