@@ -245,18 +245,17 @@ type SpannerConn interface {
245245var _ SpannerConn = & conn {}
246246
247247type conn struct {
248- parser * statementParser
249- connector * connector
250- closed bool
251- client * spanner.Client
252- adminClient * adminapi.DatabaseAdminClient
253- connId string
254- logger * slog.Logger
255- tx contextTransaction
256- prevTx contextTransaction
257- resetForRetry bool
258- commitResponse * spanner.CommitResponse
259- database string
248+ parser * statementParser
249+ connector * connector
250+ closed bool
251+ client * spanner.Client
252+ adminClient * adminapi.DatabaseAdminClient
253+ connId string
254+ logger * slog.Logger
255+ tx contextTransaction
256+ prevTx contextTransaction
257+ resetForRetry bool
258+ database string
260259
261260 execSingleQuery func (ctx context.Context , c * spanner.Client , statement spanner.Statement , bound spanner.TimestampBound , options * ExecOptions ) * spanner.RowIterator
262261 execSingleQueryTransactional func (ctx context.Context , c * spanner.Client , statement spanner.Statement , options * ExecOptions ) (rowIterator , * spanner.CommitResponse , error )
@@ -286,17 +285,33 @@ func (c *conn) UnderlyingClient() (*spanner.Client, error) {
286285}
287286
288287func (c * conn ) CommitTimestamp () (time.Time , error ) {
289- if c .commitResponse == nil {
288+ ts := propertyCommitTimestamp .GetValueOrDefault (c .state )
289+ if ts == nil {
290290 return time.Time {}, spanner .ToSpannerError (status .Error (codes .FailedPrecondition , "this connection has not executed a read/write transaction that committed successfully" ))
291291 }
292- return c . commitResponse . CommitTs , nil
292+ return * ts , nil
293293}
294294
295295func (c * conn ) CommitResponse () (commitResponse * spanner.CommitResponse , err error ) {
296- if c .commitResponse == nil {
296+ resp := propertyCommitResponse .GetValueOrDefault (c .state )
297+ if resp == nil {
297298 return nil , spanner .ToSpannerError (status .Error (codes .FailedPrecondition , "this connection has not executed a read/write transaction that committed successfully" ))
298299 }
299- return c .commitResponse , nil
300+ return resp , nil
301+ }
302+
303+ func (c * conn ) clearCommitResponse () {
304+ _ = propertyCommitResponse .SetValue (c .state , nil , connectionstate .ContextUser )
305+ _ = propertyCommitTimestamp .SetValue (c .state , nil , connectionstate .ContextUser )
306+ }
307+
308+ func (c * conn ) setCommitResponse (commitResponse * spanner.CommitResponse ) {
309+ if commitResponse == nil {
310+ c .clearCommitResponse ()
311+ return
312+ }
313+ _ = propertyCommitResponse .SetValue (c .state , commitResponse , connectionstate .ContextUser )
314+ _ = propertyCommitTimestamp .SetValue (c .state , & commitResponse .CommitTs , connectionstate .ContextUser )
300315}
301316
302317func (c * conn ) showConnectionVariable (identifier identifier ) (any , bool , error ) {
@@ -715,7 +730,6 @@ func (c *conn) ResetSession(_ context.Context) error {
715730 return driver .ErrBadConn
716731 }
717732 }
718- c .commitResponse = nil
719733 c .batch = nil
720734
721735 _ = c .state .Reset (connectionstate .ContextUser )
@@ -805,7 +819,7 @@ func (c *conn) QueryContext(ctx context.Context, query string, args []driver.Nam
805819
806820func (c * conn ) queryContext (ctx context.Context , query string , execOptions * ExecOptions , args []driver.NamedValue ) (driver.Rows , error ) {
807821 // Clear the commit timestamp of this connection before we execute the query.
808- c .commitResponse = nil
822+ c .clearCommitResponse ()
809823 // Check if the execution options contains an instruction to execute
810824 // a specific partition of a PartitionedQuery.
811825 if pq := execOptions .PartitionedQueryOptions .ExecutePartition .PartitionedQuery ; pq != nil {
@@ -830,7 +844,7 @@ func (c *conn) queryContext(ctx context.Context, query string, execOptions *Exec
830844 if err != nil {
831845 return nil , err
832846 }
833- c .commitResponse = commitResponse
847+ c .setCommitResponse ( commitResponse )
834848 } else if execOptions .PartitionedQueryOptions .PartitionQuery {
835849 return nil , spanner .ToSpannerError (status .Errorf (codes .FailedPrecondition , "PartitionQuery is only supported in batch read-only transactions" ))
836850 } else if execOptions .PartitionedQueryOptions .AutoPartitionQuery {
@@ -877,7 +891,7 @@ func (c *conn) ExecContext(ctx context.Context, query string, args []driver.Name
877891
878892func (c * conn ) execContext (ctx context.Context , query string , execOptions * ExecOptions , args []driver.NamedValue ) (driver.Result , error ) {
879893 // Clear the commit timestamp of this connection before we execute the statement.
880- c .commitResponse = nil
894+ c .clearCommitResponse ()
881895
882896 statementInfo := c .parser .detectStatementType (query )
883897 // Use admin API if DDL statement is provided.
@@ -917,7 +931,7 @@ func (c *conn) execContext(ctx context.Context, query string, execOptions *ExecO
917931 if dmlMode == Transactional {
918932 res , commitResponse , err = c .execSingleDMLTransactional (ctx , c .client , ss , statementInfo , execOptions )
919933 if err == nil {
920- c .commitResponse = commitResponse
934+ c .setCommitResponse ( commitResponse )
921935 }
922936 } else if dmlMode == PartitionedNonAtomic {
923937 var rowsAffected int64
@@ -1174,7 +1188,7 @@ func (c *conn) BeginTx(ctx context.Context, driverOpts driver.TxOptions) (driver
11741188 c .prevTx = c .tx
11751189 c .tx = nil
11761190 if commitErr == nil {
1177- c .commitResponse = commitResponse
1191+ c .setCommitResponse ( commitResponse )
11781192 if result == txResultCommit {
11791193 _ = c .state .Commit ()
11801194 } else {
@@ -1187,7 +1201,7 @@ func (c *conn) BeginTx(ctx context.Context, driverOpts driver.TxOptions) (driver
11871201 // Disable internal retries if any of these options have been set.
11881202 retryAborts : ! disableInternalRetries && ! disableRetryAborts ,
11891203 }
1190- c .commitResponse = nil
1204+ c .clearCommitResponse ()
11911205 return c .tx , nil
11921206}
11931207
0 commit comments