@@ -2099,6 +2099,12 @@ describe('Spanner with mock server', () => {
20992099 'false' ;
21002100 } ) ;
21012101
2102+ after ( ( ) => {
2103+ process . env . GOOGLE_CLOUD_SPANNER_MULTIPLEXED_SESSIONS = 'false' ;
2104+ process . env . GOOGLE_CLOUD_SPANNER_MULTIPLEXED_SESSIONS_PARTITIONED_OPS =
2105+ 'false' ;
2106+ } ) ;
2107+
21022108 it ( 'should execute the transaction(database.runPartitionedUpdate) successfully using regular/pool session' , done => {
21032109 const database = newTestDatabase ( { min : 1 , max : 1 } ) ;
21042110 const pool = ( database . sessionFactory_ as SessionFactory )
@@ -2127,6 +2133,12 @@ describe('Spanner with mock server', () => {
21272133 'true' ;
21282134 } ) ;
21292135
2136+ after ( ( ) => {
2137+ process . env . GOOGLE_CLOUD_SPANNER_MULTIPLEXED_SESSIONS = 'false' ;
2138+ process . env . GOOGLE_CLOUD_SPANNER_MULTIPLEXED_SESSIONS_PARTITIONED_OPS =
2139+ 'false' ;
2140+ } ) ;
2141+
21302142 it ( 'should execute the transaction(database.runPartitionedUpdate) successfully using regular/pool session' , done => {
21312143 const database = newTestDatabase ( { min : 1 , max : 1 } ) ;
21322144 const pool = ( database . sessionFactory_ as SessionFactory )
@@ -2154,6 +2166,12 @@ describe('Spanner with mock server', () => {
21542166 'true' ;
21552167 } ) ;
21562168
2169+ after ( ( ) => {
2170+ process . env . GOOGLE_CLOUD_SPANNER_MULTIPLEXED_SESSIONS = 'false' ;
2171+ process . env . GOOGLE_CLOUD_SPANNER_MULTIPLEXED_SESSIONS_PARTITIONED_OPS =
2172+ 'false' ;
2173+ } ) ;
2174+
21572175 it ( 'should execute the transaction(database.runPartitionedUpdate) successfully using multiplexed session' , done => {
21582176 const database = newTestDatabase ( { min : 1 , max : 1 } ) ;
21592177 const pool = ( database . sessionFactory_ as SessionFactory )
@@ -4452,6 +4470,86 @@ describe('Spanner with mock server', () => {
44524470 } ) ;
44534471 } ) ;
44544472 } ) ;
4473+
4474+ // test(s) for commit retry logic
4475+ describe ( 'Transaction Commit Retry Logic' , ( ) => {
4476+ let commitCallCount = 0 ;
4477+ let capturedCommitRequests : any [ ] = [ ] ;
4478+
4479+ it ( 'should retry commit only once with a precommit token' , async ( ) => {
4480+ commitCallCount = 0 ;
4481+ capturedCommitRequests = [ ] ;
4482+
4483+ const database = newTestDatabase ( { min : 1 , max : 1 } ) ;
4484+ const fakeRetryToken = Buffer . from ( 'mock-retry-token-123' ) ;
4485+
4486+ const commitRetryResponse = {
4487+ MultiplexedSessionRetry : 'precommitToken' ,
4488+ precommitToken : {
4489+ precommitToken : fakeRetryToken ,
4490+ seqNum : 1 ,
4491+ } ,
4492+ commitTimestamp : mock . now ( ) ,
4493+ } ;
4494+
4495+ const commitSuccessResponse = {
4496+ commitTimestamp : mock . now ( ) ,
4497+ } ;
4498+
4499+ await database . runTransactionAsync ( async tx => {
4500+ // mock commit request
4501+ tx . request = ( config : any , callback : Function ) => {
4502+ const cb = callback as ( err : any , response : any ) => void ;
4503+
4504+ if ( config . method !== 'commit' ) return ;
4505+
4506+ commitCallCount ++ ;
4507+ capturedCommitRequests . push ( config . reqOpts ) ;
4508+
4509+ if ( commitCallCount === 1 ) {
4510+ cb ( null , commitRetryResponse ) ;
4511+ } else {
4512+ cb ( null , commitSuccessResponse ) ;
4513+ }
4514+ } ;
4515+
4516+ // perform read
4517+ await tx ! . run ( selectSql ) ;
4518+
4519+ // perform mutations
4520+ await tx . upsert ( 'foo' , [
4521+ { id : 1 , name : 'One' } ,
4522+ { id : 2 , name : 'Two' } ,
4523+ ] ) ;
4524+
4525+ // make a call to commit
4526+ await tx . commit ( ) ;
4527+
4528+ // assert that retry heppen only once
4529+ assert . strictEqual (
4530+ commitCallCount ,
4531+ 2 ,
4532+ 'The mock commit method should have been called exactly twice.' ,
4533+ ) ;
4534+ const firstRequest = capturedCommitRequests [ 0 ] ;
4535+ // assert that during the first request to commit
4536+ // the precommitToken was missing
4537+ assert . ok (
4538+ ! firstRequest . precommitToken ,
4539+ 'The first commit request should not have a precommitToken.' ,
4540+ ) ;
4541+ const secondRequest = capturedCommitRequests [ 1 ] ;
4542+ // assert that during the second request to commit
4543+ // the precommitToken was present
4544+ assert . deepStrictEqual (
4545+ secondRequest . precommitToken ,
4546+ commitRetryResponse . precommitToken ,
4547+ 'The second commit request should have the precommitToken from the retry response.' ,
4548+ ) ;
4549+ } ) ;
4550+ await database . close ( ) ;
4551+ } ) ;
4552+ } ) ;
44554553 } ) ;
44564554 } ) ;
44574555
0 commit comments