Skip to content

Add intelligence to the AWS JDBC wrapper to Auto-detect and set readOnly=true flag based on query nature(SELECT * from... queries), eliminating mandatory @Transactional(readOnly=true) in Spring applications. #1563

@beingaryan

Description

@beingaryan

Describe the feature

Description

Add intelligence to the AWS JDBC wrapper to automatically set readOnly=true for transactions that only contain SELECT queries, eliminating the need for explicit annotation with @transactional(readOnly=true) in Spring applications.

Problem Statement

Currently, developers must manually annotate methods with @Transactional(readOnly=true) to optimize read-only transactions.
It has below challenges:

  • Creates potential for human error if annotations are forgotten
  • Increases code verbosity
  • Requires developers to understand the performance implications of read-only transactions

Proposed Solution

Implement a wrapperplugin in the AWS JDBC wrapper that:

  • Inspects SQL statements before execution
  • Automatically sets readOnly=true for connections when only SELECT statements are detected.
  • If this plugin is enabled along with readWriteSplitting, it will automatically redirects the query to reader instances, without explicitly setting @Transactional(readOnly=true)
  • Provides configuration options to enable/disable this feature.
  • aws.jdbc.autoReadOnly.enabled=true

Scenarios

  • As there can be below kinds of queries for interacting with SQL databases
  1. NATIVE QUERY
  2. JPA BASED QUERY

Benefits

  • Performance optimization: Read-only transactions can be optimized by the database
  • Reduced boilerplate: No need for explicit @transactional(readOnly=true) annotations
  • Error prevention: Eliminates human error in forgetting to set read-only flag

Sample code snippet for this
`public class AutoReadOnlyConnectionWrapper implements ConnectionPlugin {
private boolean enabled = false;
private static final Pattern SELECT_PATTERN = Pattern.compile("^\sSELECT\s+.", Pattern.CASE_INSENSITIVE);

@Override
public Connection connect(ConnectionPlugin next, ConnectionPluginContext ctx) throws SQLException {
    Connection connection = next.connect(ctx);
    if (enabled) {
        return new ReadOnlyAwareConnection(connection);
    }
    return connection;
}

private static class ReadOnlyAwareConnection implements Connection {
    private final Connection delegate;
    private boolean containsWriteOperations = false;
    
    // Implementation that monitors statements and sets readOnly appropriately
    @Override
    public PreparedStatement prepareStatement(String sql) throws SQLException {
        if (!SELECT_PATTERN.matcher(sql).matches()) {
            containsWriteOperations = true;
            delegate.setReadOnly(false);
        } else if (!containsWriteOperations) {
            delegate.setReadOnly(true);
        }
        return delegate.prepareStatement(sql);
    }
    
    // Other methods delegated to the underlying connection
}

}`

Use Case

  • Performance optimization: Read-only transactions can be optimized by the database
  • Reduced boilerplate: No need for explicit @transactional(readOnly=true) annotations
  • Error prevention: Eliminates human error in forgetting to set read-only flag

Proposed Solution

Implement a wrapperplugin in the AWS JDBC wrapper that:

  • Inspects SQL statements before execution
  • Automatically sets readOnly=true for connections when only SELECT statements are detected.
  • If this plugin is enabled along with readWriteSplitting, it will automatically redirects the query to reader instances, without explicitly setting @Transactional(readOnly=true)
  • Provides configuration options to enable/disable this feature.
  • aws.jdbc.autoReadOnly.enabled=true

Other Information

No response

Acknowledgements

  • I may be able to implement this feature request
  • This feature might incur a breaking change

The AWS Advanced JDBC Driver version used

2.5.6

JDK version used

17

Operating System and version

WIN11

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions