Skip to content

Commit aba7e6b

Browse files
docs: internal connection pool for Spring apps (#869)
Co-authored-by: crystall-bitquill <[email protected]>
1 parent b99e433 commit aba7e6b

File tree

2 files changed

+17
-14
lines changed

2 files changed

+17
-14
lines changed

docs/using-the-jdbc-driver/ConfigurationPresets.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ Configuration Presets are optimized for 3 main user scenarios. They are:
3535

3636
Some preset names may include a number, like `A0`, `A1`, `A2`, `D0`, `D1`, etc. Usually, the number represent sensitivity or timing variations for the same preset. For example, `A0` is optimized for normal network outage sensitivity and normal response time, while `A1` is less sensitive. Please take into account that more aggressive presets tend to cause more false positive failure detections. More details can be found in this file: [ConfigurationProfilePresetCodes.java](./../../wrapper/src/main/java/software/amazon/jdbc/profile/ConfigurationProfilePresetCodes.java)
3737

38+
Configuration presets starting with the `SF_` prefix are optimized for Spring Framework/Boot applications. These presets correspond to the same presets with no such prefix, but have the [Read/Write Splitting Plugin](./using-plugins/UsingTheReadWriteSplittingPlugin.md) disabled. For instance, the preset `SF_A0` is the Spring Framework optimized version of the `A0` preset. More details are available at [Read/Write Splitting Plugin Example](./using-the-jdbc-driver/using-plugins/UsingTheReadWriteSplittingPlugin.md#example). Since the `SF_` presets are functionally equivalent to their corresponding generic presets, more information on each `SF_` preset can be found in the diagram below in the corresponding generic preset section.
39+
3840
Choosing the right configuration preset for your application can be a challenging task. Many presets could potentially fit the needs of your application. Various user application requirements and goals are presented in the following table and organized to help you identify the most suitable presets for your application.
3941

4042
PDF version of the following table can be found [here](./../files/configuration-profile-presets.pdf).

docs/using-the-jdbc-driver/using-plugins/UsingTheReadWriteSplittingPlugin.md

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,6 @@ private static String getPoolKey(HostSpec hostSpec, Properties props) {
7979
> [!IMPORTANT]\
8080
> You must call `ConnectionProviderManager.releaseResources` to close the internal connection pools when you are finished using all connections. Unless `ConnectionProviderManager.releaseResources` is called, the wrapper driver will keep the pools open so that they can be shared between connections.
8181
82-
## Example
83-
[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.
84-
8582
## Reader Selection Strategies
8683
By default, the read/write plugin randomly selects a reader instance the first time that `setReadOnly(true)` is called. To balance connections to reader instances more evenly, different selection strategies can be used. The following table describes the currently available selection strategies and any relevant configuration parameters for each strategy.
8784

@@ -105,27 +102,31 @@ props.setProperty(ReadWriteSplittingPlugin.READER_HOST_SELECTOR_STRATEGY.name, "
105102

106103
When a Statement or ResultSet is created, it is internally bound to the database connection established at that moment. There is no standard JDBC functionality to change the internal connection used by Statement or ResultSet objects. Consequently, even if the read/write plugin switches the internal connection, any Statements/ResultSets created before this will continue using the old database connection. This bypasses the desired functionality provided by the plugin. To prevent these scenarios, an exception will be thrown if your code uses any Statements/ResultSets created before a change in internal connection. To solve this problem, please ensure you create new Statement/ResultSet objects after switching between the writer/reader.
107104

108-
### Session state limitations
109-
110-
There are many session state attributes that can change during a session, and many ways to change them. Consequently, the read/write splitting plugin has limited support for transferring session state between connections. The following attributes will be automatically transferred when switching connections:
105+
### Session state
111106

112-
- autocommit value
113-
- transaction isolation level
114-
115-
All other session state attributes will be lost when switching connections between the writer/reader.
116-
117-
If your SQL workflow depends on session state attributes that are not mentioned above, you will need to re-configure those attributes each time that you switch between the writer/reader.
107+
The plugin supports session state transfer when switching connection. All attributes mentioned in [Session State](../SessionState.md) are automatically transferred to a new connection.
118108

119109

120110
### Limitations when using Spring Boot/Framework
121111

122112
#### @Transactional(readOnly = True)
123113

124114
> [!WARNING]\
125-
> The use of read/write splitting with the annotation @Transactional(readOnly = True) is not recommended.
115+
> The use of read/write splitting with the annotation @Transactional(readOnly = True) is **only** recommended for configurations using an internal connection pool. Using the annotation with any other configurations will cause a significant performance degradation.
126116
127117
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.
128118

129119
#### Internal connection pools
130120

131-
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.
121+
If you want to use the driver's internal connection pooling, we recommend that you explicitly disable external connection pools (provided by Spring). You need to 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.
122+
123+
Spring applications are encouraged to use configuration profiles and presets optimized specifically for Spring applications. More details are available at [Configuration Presets](../ConfigurationPresets.md).
124+
125+
126+
## Example
127+
[ReadWriteSplittingPostgresExample.java](../../../examples/AWSDriverExample/src/main/java/software/amazon/ReadWriteSplittingPostgresExample.java) demonstrates how to enable and configure Read/Write Splitting with the AWS JDBC Driver.
128+
129+
[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 pooling and provides a load-balanced reader connection according to a specified reader selection strategy. `@Transactional(readOnly = True)` annotations in the code help the `Read/Write Splitting Plugin` switch between datasources.
130+
131+
[SpringHibernateBalancedReaderTwoDataSourceExample](../../../examples/SpringHibernateBalancedReaderTwoDataSourceExample/README.md) demonstrates how to enable and configure Read/Write Splitting plugin with the AWS JDBC Driver. This example application uses a configuration with two Spring datasources, where each datasource uses internal connection pooling. The example application provides a load-balanced reader connection according to a specified reader selection strategy. The example application does not use the `Read/Write Splitting Plugin`. Switching between the writer datasource and reader datasource occurs with the help of the `@WithLoadBalancedReaderDataSource` annotation.
132+

0 commit comments

Comments
 (0)