@@ -2358,6 +2358,91 @@ public void testBatchWriteAtLeastOnce() {
23582358 assertEquals (2L , client .multiplexedSessionDatabaseClient .getNumSessionsReleased ().get ());
23592359 }
23602360
2361+ @ Test
2362+ public void
2363+ testRWTransactionWithAsyncTransactionManager_CommitAborted_SetsTransactionId_AndUsedInNewInstance ()
2364+ throws Exception {
2365+ // This test performs the following steps:
2366+ // 1. Simulates an ABORTED exception during ExecuteSQL and verifies that the transaction ID is
2367+ // included in the AbortedException.
2368+ // 2. Passes the ABORTED exception to the begin(AbortedException) method of a new
2369+ // AsyncTransactionManager, and verifies that the transaction ID from the failed transaction is
2370+ // sent
2371+ // during the inline begin of the first request.
2372+ DatabaseClientImpl client =
2373+ (DatabaseClientImpl ) spanner .getDatabaseClient (DatabaseId .of ("p" , "i" , "d" ));
2374+ // Force the Commit RPC to return Aborted the first time it is called. The exception is cleared
2375+ // after the first call, so the retry should succeed.
2376+ mockSpanner .setCommitExecutionTime (
2377+ SimulatedExecutionTime .ofException (
2378+ mockSpanner .createAbortedException (ByteString .copyFromUtf8 ("test" ))));
2379+ ByteString abortedTransactionID = null ;
2380+ AbortedException exception = null ;
2381+ try (AsyncTransactionManager manager = client .transactionManagerAsync ()) {
2382+ TransactionContextFuture transactionContextFuture = manager .beginAsync ();
2383+ try {
2384+ AsyncTransactionStep <Void , Long > updateCount =
2385+ transactionContextFuture .then (
2386+ (transaction , ignored ) -> transaction .executeUpdateAsync (UPDATE_STATEMENT ),
2387+ MoreExecutors .directExecutor ());
2388+ CommitTimestampFuture commitTimestamp = updateCount .commitAsync ();
2389+ assertEquals (UPDATE_COUNT , updateCount .get ().longValue ());
2390+ assertNotNull (commitTimestamp .get ());
2391+ } catch (AbortedException e ) {
2392+ assertNotNull (e .getTransactionID ());
2393+ exception = e ;
2394+ abortedTransactionID = e .getTransactionID ();
2395+ }
2396+ }
2397+
2398+ // Verify that the transactionID of the aborted transaction is set.
2399+ assertNotNull (abortedTransactionID );
2400+ assertNotNull (exception );
2401+ mockSpanner .clearRequests ();
2402+
2403+ try (AsyncTransactionManager manager = client .transactionManagerAsync ()) {
2404+ TransactionContextFuture transactionContextFuture = manager .beginAsync (exception );
2405+ while (true ) {
2406+ try {
2407+ AsyncTransactionStep <Void , Long > updateCount =
2408+ transactionContextFuture .then (
2409+ (transaction , ignored ) -> transaction .executeUpdateAsync (UPDATE_STATEMENT ),
2410+ MoreExecutors .directExecutor ());
2411+ CommitTimestampFuture commitTimestamp = updateCount .commitAsync ();
2412+ assertEquals (UPDATE_COUNT , updateCount .get ().longValue ());
2413+ assertNotNull (commitTimestamp .get ());
2414+ break ;
2415+ } catch (AbortedException e ) {
2416+ transactionContextFuture = manager .resetForRetryAsync ();
2417+ }
2418+ }
2419+ }
2420+
2421+ List <ExecuteSqlRequest > executeSqlRequests =
2422+ mockSpanner .getRequestsOfType (ExecuteSqlRequest .class );
2423+ assertEquals (1 , executeSqlRequests .size ());
2424+ assertTrue (mockSpanner .getSession (executeSqlRequests .get (0 ).getSession ()).getMultiplexed ());
2425+ assertNotNull (
2426+ executeSqlRequests
2427+ .get (0 )
2428+ .getTransaction ()
2429+ .getBegin ()
2430+ .getReadWrite ()
2431+ .getMultiplexedSessionPreviousTransactionId ());
2432+ assertEquals (
2433+ executeSqlRequests
2434+ .get (0 )
2435+ .getTransaction ()
2436+ .getBegin ()
2437+ .getReadWrite ()
2438+ .getMultiplexedSessionPreviousTransactionId (),
2439+ abortedTransactionID );
2440+
2441+ assertNotNull (client .multiplexedSessionDatabaseClient );
2442+ assertEquals (2L , client .multiplexedSessionDatabaseClient .getNumSessionsAcquired ().get ());
2443+ assertEquals (2L , client .multiplexedSessionDatabaseClient .getNumSessionsReleased ().get ());
2444+ }
2445+
23612446 private void waitForSessionToBeReplaced (DatabaseClientImpl client ) {
23622447 assertNotNull (client .multiplexedSessionDatabaseClient );
23632448 SessionReference sessionReference =
0 commit comments