Skip to content
This repository was archived by the owner on Apr 7, 2026. It is now read-only.

Commit 368927e

Browse files
committed
Merge branch 'main' into PR #3928 to update
2 parents 147189c + e3fa634 commit 368927e

23 files changed

Lines changed: 493 additions & 98 deletions

File tree

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
# Changelog
22

3+
## [6.106.0](https://github.com/googleapis/java-spanner/compare/v6.105.0...v6.106.0) (2026-01-07)
4+
5+
6+
### Features
7+
8+
* Support SHOW DEFAULT_TRANSACTION_ISOLATION for PG databases ([#4285](https://github.com/googleapis/java-spanner/issues/4285)) ([aec0515](https://github.com/googleapis/java-spanner/commit/aec051514dd3d122a7231eb6d25d1aaec8d90bda))
9+
10+
11+
### Bug Fixes
12+
13+
* Adjust the initial polling delay for ddl operations ([#4275](https://github.com/googleapis/java-spanner/issues/4275)) ([8d36967](https://github.com/googleapis/java-spanner/commit/8d36967d010bed8f5a4a0c32f9ec1b5fe7d33e1d))
14+
* Retry creation of multiplexed session ([#4288](https://github.com/googleapis/java-spanner/issues/4288)) ([735e29e](https://github.com/googleapis/java-spanner/commit/735e29ed394faea9f5e697b5934a1f4895055d56))
15+
316
## [6.105.0](https://github.com/googleapis/java-spanner/compare/v6.104.0...v6.105.0) (2025-12-16)
417

518

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,13 @@ implementation 'com.google.cloud:google-cloud-spanner'
5656
If you are using Gradle without BOM, add this to your dependencies:
5757

5858
```Groovy
59-
implementation 'com.google.cloud:google-cloud-spanner:6.105.0'
59+
implementation 'com.google.cloud:google-cloud-spanner:6.106.0'
6060
```
6161

6262
If you are using SBT, add this to your dependencies:
6363

6464
```Scala
65-
libraryDependencies += "com.google.cloud" % "google-cloud-spanner" % "6.105.0"
65+
libraryDependencies += "com.google.cloud" % "google-cloud-spanner" % "6.106.0"
6666
```
6767

6868
## Authentication
@@ -567,7 +567,7 @@ Java is a registered trademark of Oracle and/or its affiliates.
567567
[kokoro-badge-link-5]: http://storage.googleapis.com/cloud-devrel-public/java/badges/java-spanner/java11.html
568568
[stability-image]: https://img.shields.io/badge/stability-stable-green
569569
[maven-version-image]: https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-spanner.svg
570-
[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-spanner/6.105.0
570+
[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-spanner/6.106.0
571571
[authentication]: https://github.com/googleapis/google-cloud-java#authentication
572572
[auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes
573573
[predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles

benchmarks/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
<parent>
2525
<groupId>com.google.cloud</groupId>
2626
<artifactId>google-cloud-spanner-parent</artifactId>
27-
<version>6.105.1-SNAPSHOT</version><!-- {x-version-update:google-cloud-spanner:current} -->
27+
<version>6.106.0</version><!-- {x-version-update:google-cloud-spanner:current} -->
2828
</parent>
2929

3030
<properties>

google-cloud-spanner-bom/pom.xml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<modelVersion>4.0.0</modelVersion>
44
<groupId>com.google.cloud</groupId>
55
<artifactId>google-cloud-spanner-bom</artifactId>
6-
<version>6.105.1-SNAPSHOT</version><!-- {x-version-update:google-cloud-spanner:current} -->
6+
<version>6.106.0</version><!-- {x-version-update:google-cloud-spanner:current} -->
77
<packaging>pom</packaging>
88
<parent>
99
<groupId>com.google.cloud</groupId>
@@ -53,43 +53,43 @@
5353
<dependency>
5454
<groupId>com.google.cloud</groupId>
5555
<artifactId>google-cloud-spanner</artifactId>
56-
<version>6.105.1-SNAPSHOT</version><!-- {x-version-update:google-cloud-spanner:current} -->
56+
<version>6.106.0</version><!-- {x-version-update:google-cloud-spanner:current} -->
5757
</dependency>
5858
<dependency>
5959
<groupId>com.google.cloud</groupId>
6060
<artifactId>google-cloud-spanner</artifactId>
6161
<type>test-jar</type>
62-
<version>6.105.1-SNAPSHOT</version><!-- {x-version-update:google-cloud-spanner:current} -->
62+
<version>6.106.0</version><!-- {x-version-update:google-cloud-spanner:current} -->
6363
</dependency>
6464
<dependency>
6565
<groupId>com.google.api.grpc</groupId>
6666
<artifactId>grpc-google-cloud-spanner-v1</artifactId>
67-
<version>6.105.1-SNAPSHOT</version><!-- {x-version-update:grpc-google-cloud-spanner-v1:current} -->
67+
<version>6.106.0</version><!-- {x-version-update:grpc-google-cloud-spanner-v1:current} -->
6868
</dependency>
6969
<dependency>
7070
<groupId>com.google.api.grpc</groupId>
7171
<artifactId>grpc-google-cloud-spanner-admin-instance-v1</artifactId>
72-
<version>6.105.1-SNAPSHOT</version><!-- {x-version-update:grpc-google-cloud-spanner-admin-instance-v1:current} -->
72+
<version>6.106.0</version><!-- {x-version-update:grpc-google-cloud-spanner-admin-instance-v1:current} -->
7373
</dependency>
7474
<dependency>
7575
<groupId>com.google.api.grpc</groupId>
7676
<artifactId>grpc-google-cloud-spanner-admin-database-v1</artifactId>
77-
<version>6.105.1-SNAPSHOT</version><!-- {x-version-update:grpc-google-cloud-spanner-admin-database-v1:current} -->
77+
<version>6.106.0</version><!-- {x-version-update:grpc-google-cloud-spanner-admin-database-v1:current} -->
7878
</dependency>
7979
<dependency>
8080
<groupId>com.google.api.grpc</groupId>
8181
<artifactId>proto-google-cloud-spanner-admin-instance-v1</artifactId>
82-
<version>6.105.1-SNAPSHOT</version><!-- {x-version-update:proto-google-cloud-spanner-admin-instance-v1:current} -->
82+
<version>6.106.0</version><!-- {x-version-update:proto-google-cloud-spanner-admin-instance-v1:current} -->
8383
</dependency>
8484
<dependency>
8585
<groupId>com.google.api.grpc</groupId>
8686
<artifactId>proto-google-cloud-spanner-v1</artifactId>
87-
<version>6.105.1-SNAPSHOT</version><!-- {x-version-update:proto-google-cloud-spanner-v1:current} -->
87+
<version>6.106.0</version><!-- {x-version-update:proto-google-cloud-spanner-v1:current} -->
8888
</dependency>
8989
<dependency>
9090
<groupId>com.google.api.grpc</groupId>
9191
<artifactId>proto-google-cloud-spanner-admin-database-v1</artifactId>
92-
<version>6.105.1-SNAPSHOT</version><!-- {x-version-update:proto-google-cloud-spanner-admin-database-v1:current} -->
92+
<version>6.106.0</version><!-- {x-version-update:proto-google-cloud-spanner-admin-database-v1:current} -->
9393
</dependency>
9494
</dependencies>
9595
</dependencyManagement>

google-cloud-spanner-executor/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55
<modelVersion>4.0.0</modelVersion>
66
<groupId>com.google.cloud</groupId>
77
<artifactId>google-cloud-spanner-executor</artifactId>
8-
<version>6.105.1-SNAPSHOT</version><!-- {x-version-update:google-cloud-spanner-executor:current} -->
8+
<version>6.106.0</version><!-- {x-version-update:google-cloud-spanner-executor:current} -->
99
<packaging>jar</packaging>
1010
<name>Google Cloud Spanner Executor</name>
1111

1212
<parent>
1313
<groupId>com.google.cloud</groupId>
1414
<artifactId>google-cloud-spanner-parent</artifactId>
15-
<version>6.105.1-SNAPSHOT</version><!-- {x-version-update:google-cloud-spanner:current} -->
15+
<version>6.106.0</version><!-- {x-version-update:google-cloud-spanner:current} -->
1616
</parent>
1717

1818
<properties>

google-cloud-spanner/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@
33
<modelVersion>4.0.0</modelVersion>
44
<groupId>com.google.cloud</groupId>
55
<artifactId>google-cloud-spanner</artifactId>
6-
<version>6.105.1-SNAPSHOT</version><!-- {x-version-update:google-cloud-spanner:current} -->
6+
<version>6.106.0</version><!-- {x-version-update:google-cloud-spanner:current} -->
77
<packaging>jar</packaging>
88
<name>Google Cloud Spanner</name>
99
<url>https://github.com/googleapis/java-spanner</url>
1010
<description>Java idiomatic client for Google Cloud Spanner.</description>
1111
<parent>
1212
<groupId>com.google.cloud</groupId>
1313
<artifactId>google-cloud-spanner-parent</artifactId>
14-
<version>6.105.1-SNAPSHOT</version><!-- {x-version-update:google-cloud-spanner:current} -->
14+
<version>6.106.0</version><!-- {x-version-update:google-cloud-spanner:current} -->
1515
</parent>
1616
<properties>
1717
<site.installationModule>google-cloud-spanner</site.installationModule>

google-cloud-spanner/src/main/java/com/google/cloud/spanner/MultiplexedSessionDatabaseClient.java

Lines changed: 59 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import java.time.Duration;
4141
import java.time.Instant;
4242
import java.util.BitSet;
43+
import java.util.EnumSet;
4344
import java.util.HashMap;
4445
import java.util.Map;
4546
import java.util.concurrent.ExecutionException;
@@ -262,6 +263,9 @@ public void close() {
262263
*/
263264
private static final Map<SpannerImpl, BitSet> CHANNEL_USAGE = new HashMap<>();
264265

266+
private static final EnumSet<ErrorCode> RETRYABLE_ERROR_CODES =
267+
EnumSet.of(ErrorCode.DEADLINE_EXCEEDED, ErrorCode.RESOURCE_EXHAUSTED, ErrorCode.UNAVAILABLE);
268+
265269
private final BitSet channelUsage;
266270

267271
private final int numChannels;
@@ -358,11 +362,19 @@ public void close() {
358362
SettableApiFuture.create();
359363
this.readWriteBeginTransactionReferenceFuture = SettableApiFuture.create();
360364
this.multiplexedSessionReference = new AtomicReference<>(initialSessionReferenceFuture);
365+
asyncCreateMultiplexedSession(initialSessionReferenceFuture);
366+
maybeWaitForSessionCreation(
367+
sessionClient.getSpanner().getOptions().getSessionPoolOptions(),
368+
initialSessionReferenceFuture);
369+
}
370+
371+
private void asyncCreateMultiplexedSession(
372+
SettableApiFuture<SessionReference> sessionReferenceFuture) {
361373
this.sessionClient.asyncCreateMultiplexedSession(
362374
new SessionConsumer() {
363375
@Override
364376
public void onSessionReady(SessionImpl session) {
365-
initialSessionReferenceFuture.set(session.getSessionReference());
377+
sessionReferenceFuture.set(session.getSessionReference());
366378
// only start the maintainer if we actually managed to create a session in the first
367379
// place.
368380
maintainer.start();
@@ -395,33 +407,62 @@ public void onSessionCreateFailure(Throwable t, int createFailureForSessionCount
395407
// Mark multiplexes sessions as unimplemented and fall back to regular sessions if
396408
// UNIMPLEMENTED is returned.
397409
maybeMarkUnimplemented(t);
398-
initialSessionReferenceFuture.setException(t);
410+
sessionReferenceFuture.setException(t);
399411
}
400412
});
401-
maybeWaitForSessionCreation(
402-
sessionClient.getSpanner().getOptions().getSessionPoolOptions(),
403-
initialSessionReferenceFuture);
404413
}
405414

406415
void setPool(SessionPool pool) {
407416
this.pool = pool;
408417
}
409418

410-
private static void maybeWaitForSessionCreation(
411-
SessionPoolOptions sessionPoolOptions, ApiFuture<SessionReference> future) {
419+
private void maybeWaitForSessionCreation(
420+
SessionPoolOptions sessionPoolOptions,
421+
SettableApiFuture<SessionReference> initialSessionReferenceFuture) {
412422
Duration waitDuration = sessionPoolOptions.getWaitForMinSessions();
413423
if (waitDuration != null && !waitDuration.isZero()) {
414-
long timeoutMillis = waitDuration.toMillis();
415-
try {
416-
future.get(timeoutMillis, TimeUnit.MILLISECONDS);
417-
} catch (ExecutionException executionException) {
418-
throw SpannerExceptionFactory.asSpannerException(executionException.getCause());
419-
} catch (InterruptedException interruptedException) {
420-
throw SpannerExceptionFactory.propagateInterrupt(interruptedException);
421-
} catch (TimeoutException timeoutException) {
422-
throw SpannerExceptionFactory.newSpannerException(
423-
ErrorCode.DEADLINE_EXCEEDED,
424-
"Timed out after waiting " + timeoutMillis + "ms for multiplexed session creation");
424+
425+
SpannerException lastException = null;
426+
SettableApiFuture<SessionReference> sessionReferenceFuture = initialSessionReferenceFuture;
427+
Duration remainingTime;
428+
429+
Instant endTime = Instant.now().plus(waitDuration);
430+
while ((remainingTime = Duration.between(Instant.now(), endTime)).toMillis() > 0) {
431+
// If any exception is thrown, then retry the multiplexed session creation
432+
if (sessionReferenceFuture == null) {
433+
sessionReferenceFuture = SettableApiFuture.create();
434+
asyncCreateMultiplexedSession(sessionReferenceFuture);
435+
this.multiplexedSessionReference.set(sessionReferenceFuture);
436+
}
437+
try {
438+
sessionReferenceFuture.get(remainingTime.toMillis(), TimeUnit.MILLISECONDS);
439+
lastException = null;
440+
break;
441+
} catch (ExecutionException executionException) {
442+
lastException = SpannerExceptionFactory.asSpannerException(executionException.getCause());
443+
} catch (InterruptedException interruptedException) {
444+
lastException = SpannerExceptionFactory.propagateInterrupt(interruptedException);
445+
} catch (TimeoutException timeoutException) {
446+
lastException =
447+
SpannerExceptionFactory.newSpannerException(
448+
ErrorCode.DEADLINE_EXCEEDED,
449+
"Timed out after waiting "
450+
+ waitDuration.toMillis()
451+
+ "ms for multiplexed session creation");
452+
}
453+
// if any exception is thrown, then set the session reference to null to retry the
454+
// multiplexed session creation only if the error code is DEADLINE EXCEEDED, UNAVAILABLE or
455+
// RESOURCE_EXHAUSTED
456+
if (RETRYABLE_ERROR_CODES.contains(lastException.getErrorCode())) {
457+
sessionReferenceFuture = null;
458+
} else {
459+
break;
460+
}
461+
}
462+
// if the wait time elapsed and multiplexed session fetch failed then throw the last exception
463+
// that we have received
464+
if (lastException != null) {
465+
throw lastException;
425466
}
426467
}
427468
}

0 commit comments

Comments
 (0)