Skip to content

Commit

Permalink
fix(spanner): prevent possible panic for Session not found errors (#1…
Browse files Browse the repository at this point in the history
…0386)

The Spanner client library could panic if specifically the following
situation would occur:
1. Create a StmtBasedReadWriteTransaction
2. Only execute mutations, so that an explicit BeginTransaction
   RPC is required.
3. The BeginTransaction RPC returns "Session not found"
4. The client library tries to get a new session from the pool.

Step 4 above would panic, because the client library did not set the
readOnlyTransaction.sp field for StmtBasedReadWriteTransactions.

Fixes #10385

Co-authored-by: rahul2393 <irahul@google.com>
  • Loading branch information
olavloite and rahul2393 authored Jun 18, 2024
1 parent 1e2af81 commit ba9711f
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 0 deletions.
15 changes: 15 additions & 0 deletions spanner/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3474,6 +3474,21 @@ func TestReadWriteTransaction_WrapSessionNotFoundError(t *testing.T) {
}
}

func TestStmtBasedReadWriteTransaction_SessionNotFoundError_shouldNotPanic(t *testing.T) {
t.Parallel()
server, client, teardown := setupMockedTestServer(t)
defer teardown()
server.TestSpanner.PutExecutionTime(MethodBeginTransaction,
SimulatedExecutionTime{
Errors: []error{newSessionNotFoundError("projects/p/instances/i/databases/d/sessions/s")},
})
ctx := context.Background()
tx, _ := NewReadWriteStmtBasedTransaction(ctx, client)
_ = tx.BufferWrite([]*Mutation{Update("my_table", []string{"key", "value"}, []interface{}{int64(1), "my-value"})})
// This would panic, as it could not refresh the session.
_, _ = tx.Commit(ctx)
}

func TestClient_WriteStructWithPointers(t *testing.T) {
t.Parallel()
server, client, teardown := setupMockedTestServer(t)
Expand Down
1 change: 1 addition & 0 deletions spanner/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -1756,6 +1756,7 @@ func NewReadWriteStmtBasedTransactionWithOptions(ctx context.Context, c *Client,
txReadyOrClosed: make(chan struct{}),
},
}
t.txReadOnly.sp = c.idleSessions
t.txReadOnly.sh = sh
t.txReadOnly.txReadEnv = t
t.txReadOnly.qo = c.qo
Expand Down

0 comments on commit ba9711f

Please sign in to comment.