-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Closed
Labels
api: spannerIssues related to the Spanner API.Issues related to the Spanner API.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.Error or flaw in code with unintended results or allowing sub-optimal usage patterns.
Description
When using TransactionRunner.allowNestedTransaction, the outermost (first in order) RW transaction which allows others transaction to be nested do not return a session to the pool back.
Environment details
Env:
Library version: 1.43.0 (com.google.cloud:google-cloud-spanner:1.43.0)
Java version: 1.8.0_211
Code example
SpannerOptions options = SpannerOptions.newBuilder()
.setProjectId("<project id>")
.setCredentials(buildCredentials())
.setSessionPoolOption(SessionPoolOptions.newBuilder()
.setMinSessions(4)
.setMaxSessions(4)
.setFailIfPoolExhausted()
.build())
.build();
try (Spanner spanner = options.getService()) {
DatabaseId dbOne = DatabaseId.of(options.getProjectId(), "instanceOne", "db");
DatabaseId dbTwo = DatabaseId.of(options.getProjectId(), "instanceTwo, "db");
DatabaseClient dbClientOne = spanner.getDatabaseClient(dbOne);
DatabaseClient dbClientTwo = spanner.getDatabaseClient(dbTwo);
for (int i = 0; i < 10; i++) {
Long result = dbClientOne.readWriteTransaction().allowNestedTransaction().run(transaction -> {
try (ResultSet resultSet = transaction.executeQuery(Statement.of("SELECT 1"))) {
Long add = dbClientTwo.readWriteTransaction().run(transactionNested -> {
try (ResultSet resultSetTwo = transactionNested.executeQuery(Statement.of("SELECT 2"))) {
resultSetTwo.next();
return resultSetTwo.getLong(0);
}
});
resultSet.next() ;
return (resultSet.getLong(0) + add);
}
});
System.out.println(i + " " + result);
} // fails
}Other code sample (it fails also when there's a single transaction executed, no real nesting, only the option is on):
for (int i = 0; i < 10; i++) {
Long result = dbClient.readWriteTransaction().allowNestedTransaction().run(transaction -> {
try (ResultSet resultSet = transaction.executeQuery(Statement.of("SELECT 1"))) {
resultSet.next();
return (resultSet.getLong(0));
}
});
System.out.println(i + " " + result);
} // failsStack trace
Nov 04, 2019 10:53:24 AM com.google.cloud.spanner.SessionPool closeAsync
WARNING: Leaked session
com.google.cloud.spanner.SessionPool$LeakedSessionException: Session was checked out from the pool at 2019-11-04T08:53:22.802Z
at com.google.cloud.spanner.SessionPool$PooledSession.markBusy(SessionPool.java:624)
at com.google.cloud.spanner.SessionPool$PooledSession.access$4400(SessionPool.java:596)
at com.google.cloud.spanner.SessionPool.getReadWriteSession(SessionPool.java:1319)
at com.google.cloud.spanner.DatabaseClientImpl.getReadWriteSession(DatabaseClientImpl.java:57)
at com.google.cloud.spanner.DatabaseClientImpl.readWriteTransaction(DatabaseClientImpl.java:170)
at LeakTest.testWithAllowNestedTransactions(LeakTest.java:31)
Metadata
Metadata
Assignees
Labels
api: spannerIssues related to the Spanner API.Issues related to the Spanner API.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.Error or flaw in code with unintended results or allowing sub-optimal usage patterns.