Skip to content

Commit 2ce3606

Browse files
feat(spanner): inline begin transaction for ReadWriteTransactions (#7149)
* feat(spanner): inline begin transaction * fix apidiff install issue * fix github workflow install issue * add test to for a read/write transaction executing two queries in parallel as the first statement, transactionID used should be same and the other should block until the first has returned a transactionID. * incorporate requested changes * fix check * incorporate requested changes * minor fixes * fix benchmark tests * feat(spanner): testcase fixes * feat(spanner): nit add key to struct * incoporate suggested changes * incorporate requested changes * re-trigger checks Co-authored-by: harshachinta <[email protected]>
1 parent 9a6db6d commit 2ce3606

14 files changed

+751
-956
lines changed

spanner/client.go

+16-11
Original file line numberDiff line numberDiff line change
@@ -491,43 +491,48 @@ func (c *Client) rwTransaction(ctx context.Context, f func(context.Context, *Rea
491491
return resp, err
492492
}
493493
var (
494-
sh *sessionHandle
494+
sh *sessionHandle
495+
t *ReadWriteTransaction
496+
attempt = 0
495497
)
496498
defer func() {
497499
if sh != nil {
498500
sh.recycle()
499501
}
500502
}()
501-
err = runWithRetryOnAbortedOrSessionNotFound(ctx, func(ctx context.Context) error {
503+
err = runWithRetryOnAbortedOrFailedInlineBeginOrSessionNotFound(ctx, func(ctx context.Context) error {
502504
var (
503505
err error
504-
t *ReadWriteTransaction
505506
)
506507
if sh == nil || sh.getID() == "" || sh.getClient() == nil {
507508
// Session handle hasn't been allocated or has been destroyed.
508-
sh, err = c.idleSessions.takeWriteSession(ctx)
509+
sh, err = c.idleSessions.take(ctx)
509510
if err != nil {
510511
// If session retrieval fails, just fail the transaction.
511512
return err
512513
}
513-
t = &ReadWriteTransaction{
514-
tx: sh.getTransactionID(),
514+
}
515+
if t.shouldExplicitBegin(attempt) {
516+
if err = t.begin(ctx); err != nil {
517+
return spannerErrorf(codes.Internal, "error while BeginTransaction during retrying a ReadWrite transaction: %v", err)
515518
}
516519
} else {
517-
t = &ReadWriteTransaction{}
520+
t = &ReadWriteTransaction{
521+
txReadyOrClosed: make(chan struct{}),
522+
}
518523
}
524+
attempt++
519525
t.txReadOnly.sh = sh
526+
t.txReadOnly.sp = c.idleSessions
520527
t.txReadOnly.txReadEnv = t
521528
t.txReadOnly.qo = c.qo
522529
t.txReadOnly.ro = c.ro
523530
t.txOpts = c.txo.merge(options)
524531
t.ct = c.ct
525532

526-
trace.TracePrintf(ctx, map[string]interface{}{"transactionID": string(sh.getTransactionID())},
533+
trace.TracePrintf(ctx, map[string]interface{}{"transactionSelector": t.getTransactionSelector().String()},
527534
"Starting transaction attempt")
528-
if err = t.begin(ctx); err != nil {
529-
return err
530-
}
535+
531536
resp, err = t.runInTransaction(ctx, f)
532537
return err
533538
})

spanner/client_benchmarks_test.go

+10-11
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ func createBenchmarkServer(incStep uint64) (server *MockedSpannerInMemTestServer
8484
})
8585
// Wait until the session pool has been initialized.
8686
waitFor(t, func() error {
87-
if uint64(client.idleSessions.idleList.Len()+client.idleSessions.idleWriteList.Len()) == client.idleSessions.MinOpened {
87+
if uint64(client.idleSessions.idleList.Len()) == client.idleSessions.MinOpened {
8888
return nil
8989
}
9090
return fmt.Errorf("not yet initialized")
@@ -177,8 +177,8 @@ func benchmarkClientBurstRead(b *testing.B, incStep uint64) {
177177
for n := 0; n < b.N; n++ {
178178
server, client, teardown := createBenchmarkServer(incStep)
179179
sp := client.idleSessions
180-
if uint64(sp.idleList.Len()+sp.idleWriteList.Len()) != sp.MinOpened {
181-
b.Fatalf("session count mismatch\nGot: %d\nWant: %d", sp.idleList.Len()+sp.idleWriteList.Len(), sp.MinOpened)
180+
if uint64(sp.idleList.Len()) != sp.MinOpened {
181+
b.Fatalf("session count mismatch\nGot: %d\nWant: %d", sp.idleList.Len(), sp.MinOpened)
182182
}
183183

184184
totalQueries := int(sp.MaxOpened * 8)
@@ -238,8 +238,8 @@ func benchmarkClientBurstWrite(b *testing.B, incStep uint64) {
238238
for n := 0; n < b.N; n++ {
239239
server, client, teardown := createBenchmarkServer(incStep)
240240
sp := client.idleSessions
241-
if uint64(sp.idleList.Len()+sp.idleWriteList.Len()) != sp.MinOpened {
242-
b.Fatalf("session count mismatch\nGot: %d\nWant: %d", sp.idleList.Len()+sp.idleWriteList.Len(), sp.MinOpened)
241+
if uint64(sp.idleList.Len()) != sp.MinOpened {
242+
b.Fatalf("session count mismatch\nGot: %d\nWant: %d", sp.idleList.Len(), sp.MinOpened)
243243
}
244244

245245
totalUpdates := int(sp.MaxOpened * 8)
@@ -299,8 +299,8 @@ func benchmarkClientBurstReadAndWrite(b *testing.B, incStep uint64) {
299299
for n := 0; n < b.N; n++ {
300300
server, client, teardown := createBenchmarkServer(incStep)
301301
sp := client.idleSessions
302-
if uint64(sp.idleList.Len()+sp.idleWriteList.Len()) != sp.MinOpened {
303-
b.Fatalf("session count mismatch\nGot: %d\nWant: %d", sp.idleList.Len()+sp.idleWriteList.Len(), sp.MinOpened)
302+
if uint64(sp.idleList.Len()) != sp.MinOpened {
303+
b.Fatalf("session count mismatch\nGot: %d\nWant: %d", sp.idleList.Len(), sp.MinOpened)
304304
}
305305

306306
totalUpdates := int(sp.MaxOpened * 4)
@@ -378,8 +378,8 @@ func benchmarkClientSteadyIncrease(b *testing.B, incStep uint64) {
378378
for n := 0; n < b.N; n++ {
379379
server, client, teardown := createBenchmarkServer(incStep)
380380
sp := client.idleSessions
381-
if uint64(sp.idleList.Len()+sp.idleWriteList.Len()) != sp.MinOpened {
382-
b.Fatalf("session count mismatch\nGot: %d\nWant: %d", sp.idleList.Len()+sp.idleWriteList.Len(), sp.MinOpened)
381+
if uint64(sp.idleList.Len()) != sp.MinOpened {
382+
b.Fatalf("session count mismatch\nGot: %d\nWant: %d", sp.idleList.Len(), sp.MinOpened)
383383
}
384384

385385
transactions := make([]*ReadOnlyTransaction, sp.MaxOpened)
@@ -404,8 +404,7 @@ func reportBenchmark(b *testing.B, sp *sessionPool, server *MockedSpannerInMemTe
404404
b.Logf("CreateSession: %d\t", countRequests(requests, reflect.TypeOf(&sppb.CreateSessionRequest{})))
405405
b.Logf("BeginTransaction: %d\t", countRequests(requests, reflect.TypeOf(&sppb.BeginTransactionRequest{})))
406406
b.Logf("Commit: %d\t", countRequests(requests, reflect.TypeOf(&sppb.CommitRequest{})))
407-
b.Logf("ReadSessions: %d\t", sp.idleList.Len())
408-
b.Logf("WriteSessions: %d\n", sp.idleWriteList.Len())
407+
b.Logf("NumSessions: %d\t", sp.idleList.Len())
409408
}
410409

411410
func countRequests(requests []interface{}, tp reflect.Type) (count int) {

0 commit comments

Comments
 (0)