Skip to content

Spanner: Exception on BeginTransaction rpc can cause session leak #6164

Description

@olavloite

If an exception that cannot be retried occurs while executing the BeginTransaction gRPC, the Spanner session pool could leak a session.

Consider the following example:

SpannerOptions.Builder builder =
    SpannerOptions.newBuilder()
        .setProjectId("[PROJECT]")
builder.setSessionPoolOption(
    SessionPoolOptions.newBuilder()
        .setMinSessions(0)
        .setMaxSessions(2)
        .setWriteSessionsFraction(0.0f)
        .build());
Spanner spanner = builder.build().getService();
DatabaseClient client =
    spanner.getDatabaseClient(DatabaseId.of("[PROJECT]", "[INSTANCE]", "[DATABASE]"));

TransactionRunner runner = client.readWriteTransaction();
long updateCount =
    runner.run(
        new TransactionCallable<Long>() {
          @Override
          public Long run(TransactionContext transaction) throws Exception {
            return transaction.executeUpdate(UPDATE_STATEMENT);
          }
        });

The above session pool will never contain a prepared transaction, as the writeSessionsFraction is set to 0. Creating a read/write transaction will therefore always require the session pool to prepare a new session. If the BeginTransaction rpc returns a non-retryable error, the error is returned to the client, but the session that is taken to be prepared by the session pool is never returned to the session pool.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

api: spannerIssues related to the Spanner API.priority: p2Moderately-important priority. Fix may not be included in next release.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions