@@ -2012,7 +2012,7 @@ public void testBatchWriteAtLeastOnce() {
20122012
20132013 @ Test
20142014 public void
2015- testReadWriteUnimplementedError_RetriedWithRegularSessionForInFlightTransaction_FailsWithSessionNotFound () {
2015+ testReadWriteUnimplementedError_RetriedWithRegularSessionForInFlightTransaction_RetriedWithSessionNotFound () {
20162016 // Test scenario:
20172017 // 1. The initial attempt performs an inline begin using a multiplexed session, but with the
20182018 // backend flag assumed to be OFF, resulting in an UNIMPLEMENTED error.
@@ -2066,6 +2066,65 @@ public void testBatchWriteAtLeastOnce() {
20662066 assertNotEquals (executeSqlRequests .get (1 ).getSession (), executeSqlRequests .get (2 ).getSession ());
20672067 }
20682068
2069+ @ Test
2070+ public void
2071+ testReadWriteUnimplementedError_FirstSucceedsWithMux_SecondRetriedWithRegularSessionDueToUnimplementedError () {
2072+ // Test scenario:
2073+ // 1. The first read-write transaction successfully performs an inline begin using a multiplexed
2074+ // session.
2075+ // 2. The second read-write transaction attempts to execute with a multiplexed session, but
2076+ // since the backend flag is assumed to be OFF, it encounters an UNIMPLEMENTED error.
2077+ // 3. Upon encountering the UNIMPLEMENTED error, the entire transaction callable for the second
2078+ // read-write transaction is retried using a regular session.
2079+
2080+ Spanner spanner = setupSpannerForAbortedBeginTransactionTests ();
2081+
2082+ DatabaseClientImpl client =
2083+ (DatabaseClientImpl ) spanner .getDatabaseClient (DatabaseId .of ("p" , "i" , "d" ));
2084+
2085+ // First read-write transaction attempt succeeds.
2086+ TransactionRunner runner = client .readWriteTransaction ();
2087+ Long updateCount =
2088+ runner .run (
2089+ transaction -> {
2090+ return transaction .executeUpdate (UPDATE_STATEMENT );
2091+ });
2092+
2093+ assertThat (updateCount ).isEqualTo (1L );
2094+
2095+ // The ExecuteSql request is forced to fail with UNIMPLEMENTED error.
2096+ mockSpanner .setExecuteSqlExecutionTime (
2097+ SimulatedExecutionTime .ofException (
2098+ Status .UNIMPLEMENTED
2099+ .withDescription (
2100+ "Transaction type read_write not supported with multiplexed sessions" )
2101+ .asRuntimeException ()));
2102+
2103+ // Second read-write transaction on mux fails with UNIMPLEMENTED error, and then retried using
2104+ // regular session.
2105+ TransactionRunner runner1 = client .readWriteTransaction ();
2106+ Long updateCount1 =
2107+ runner1 .run (
2108+ transaction -> {
2109+ return transaction .executeUpdate (UPDATE_STATEMENT );
2110+ });
2111+
2112+ assertThat (updateCount1 ).isEqualTo (1L );
2113+
2114+ List <ExecuteSqlRequest > executeSqlRequests =
2115+ mockSpanner .getRequestsOfType (ExecuteSqlRequest .class );
2116+ assertEquals (3 , executeSqlRequests .size ());
2117+
2118+ // Verify the first BeginTransaction request is executed using multiplexed sessions.
2119+ assertTrue (mockSpanner .getSession (executeSqlRequests .get (0 ).getSession ()).getMultiplexed ());
2120+
2121+ // Verify the second BeginTransaction request is executed using multiplexed sessions.
2122+ assertTrue (mockSpanner .getSession (executeSqlRequests .get (1 ).getSession ()).getMultiplexed ());
2123+
2124+ // Verify the second BeginTransaction request is executed using regular sessions.
2125+ assertFalse (mockSpanner .getSession (executeSqlRequests .get (2 ).getSession ()).getMultiplexed ());
2126+ }
2127+
20692128 private void waitForSessionToBeReplaced (DatabaseClientImpl client ) {
20702129 assertNotNull (client .multiplexedSessionDatabaseClient );
20712130 SessionReference sessionReference =
0 commit comments