Configure transaction timeout

This page describes how to set a timeout for transactions using theSpanner client libraries. The transaction fails with aDEADLINE_EXCEEDED error if the transaction can't finish within the giventimeout value.

You can set timeout values for transactions and forRPC request statements. Setting alonger timeout value for the transaction than the timeout value for thestatement that is executed in the transaction doesn't increase thetimeout for the statement, which is constrained by its own timeout value.

Also, if the timeout error occurs during the execution of theCommit request, it's still possible that the transaction wascommitted.

You can set a transaction timeout using the Go, Java, Python, and Node.jsclient libraries.

Go

import("context""errors""fmt""io""time""cloud.google.com/go/spanner""google.golang.org/api/iterator""google.golang.org/grpc/codes")functransactionTimeout(wio.Writer,dbstring)error{ctx:=context.Background()client,err:=spanner.NewClient(ctx,db)iferr!=nil{returnerr}deferclient.Close()// Create a context with a 60-second timeout and use this context to run a read/write transaction.// This context timeout will be applied to the entire transaction, and the transaction will fail// if it cannot finish within the specified timeout value. The Spanner client library applies the// (remainder of the) timeout to each statement that is executed in the transaction.ctx,cancel:=context.WithTimeout(context.Background(),60*time.Second)defercancel()_,err=client.ReadWriteTransaction(ctx,func(ctxcontext.Context,txn*spanner.ReadWriteTransaction)error{selectStmt:=spanner.Statement{SQL:`SELECT SingerId, FirstName, LastName FROM Singers ORDER BY LastName, FirstName`,}// The context that is passed in to the transaction function should be used for each statement// is executed.iter:=txn.Query(ctx,selectStmt)deferiter.Stop()for{row,err:=iter.Next()iferrors.Is(err,iterator.Done){break}iferr!=nil{returnerr}varsingerIDint64varfirstName,lastNamestringiferr:=row.Columns(&singerID,&firstName,&lastName);err!=nil{returnerr}fmt.Fprintf(w,"%d %s %s\n",singerID,firstName,lastName)}stmt:=spanner.Statement{SQL:`INSERT INTO Singers (SingerId, FirstName, LastName)VALUES (38, 'George', 'Washington')`,}rowCount,err:=txn.Update(ctx,stmt)iferr!=nil{returnerr}fmt.Fprintf(w,"%d record(s) inserted.\n",rowCount)returnnil})// Check if an error was returned by the transaction.// The spanner.ErrCode(err) function will return codes.OK if err == nil.code:=spanner.ErrCode(err)ifcode==codes.OK{fmt.Fprintf(w,"Transaction with timeout was executed successfully\n")}elseifcode==codes.DeadlineExceeded{fmt.Fprintf(w,"Transaction timed out\n")}else{fmt.Fprintf(w,"Transaction failed with error code %v\n",code)}returnerr}

Java

importcom.google.cloud.spanner.DatabaseClient;importcom.google.cloud.spanner.DatabaseId;importcom.google.cloud.spanner.ResultSet;importcom.google.cloud.spanner.Spanner;importcom.google.cloud.spanner.SpannerOptions;importcom.google.cloud.spanner.Statement;importio.grpc.Context;importio.grpc.Context.CancellableContext;importio.grpc.Deadline;importjava.util.concurrent.Executors;importjava.util.concurrent.ScheduledExecutorService;importjava.util.concurrent.TimeUnit;/** * Sample showing how to set a timeout for an entire transaction for the Cloud Spanner Java client. */classTransactionTimeoutExample{staticvoidexecuteTransactionWithTimeout(){// TODO(developer): Replace these variables before running the sample.StringprojectId="my-project";StringinstanceId="my-instance";StringdatabaseId="my-database";executeTransactionWithTimeout(projectId,instanceId,databaseId,60L,TimeUnit.SECONDS);}// Execute a read/write transaction with a timeout for the entire transaction.staticvoidexecuteTransactionWithTimeout(StringprojectId,StringinstanceId,StringdatabaseId,longtimeoutValue,TimeUnittimeoutUnit){try(Spannerspanner=SpannerOptions.newBuilder().setProjectId(projectId).build().getService()){DatabaseClientclient=spanner.getDatabaseClient(DatabaseId.of(projectId,instanceId,databaseId));// Create a gRPC context with a deadline and with cancellation.// gRPC context deadlines require the use of a scheduled executor.ScheduledExecutorServiceexecutor=Executors.newSingleThreadScheduledExecutor();try(CancellableContextcontext=Context.current().withDeadline(Deadline.after(timeoutValue,timeoutUnit),executor).withCancellation()){context.run(()->{client.readWriteTransaction().run(transaction->{try(ResultSetresultSet=transaction.executeQuery(Statement.of("SELECT SingerId, FirstName, LastName\n"+"FROM Singers\n"+"ORDER BY LastName, FirstName"))){while(resultSet.next()){System.out.printf("%d %s %s\n",resultSet.getLong("SingerId"),resultSet.getString("FirstName"),resultSet.getString("LastName"));}}Stringsql="INSERT INTO Singers (SingerId, FirstName, LastName)\n"+"VALUES (20, 'George', 'Washington')";longrowCount=transaction.executeUpdate(Statement.of(sql));System.out.printf("%d record inserted.%n",rowCount);returnnull;});});}}}}

Node.js

/** * TODO(developer): Uncomment the following lines before running the sample. */// const projectId = 'my-project-id';// const instanceId = 'my-instance';// const databaseId = 'my-database';// Imports the Google Cloud client libraryconst{Spanner}=require('@google-cloud/spanner');// Creates a clientconstspanner=newSpanner({projectId:projectId,});asyncfunctionexecuteTransactionWithTimeout(){// Gets a reference to a Cloud Spanner instance and database.constinstance=spanner.instance(instanceId);constdatabase=instance.database(databaseId);constoptions={timeout:60000,// 60 seconds timeout};try{awaitdatabase.runTransactionAsync(options,asynctx=>{const[results]=awaittx.run('SELECT SingerId, FirstName, LastName FROM Singers ORDER BY LastName, FirstName',);results.forEach(result=>{console.log(`${result[0].name}:${result[0].value.value},${result[1].name}:${result[1].value},${result[2].name}:${result[2].value}`,);});constsql="INSERT INTO Singers (SingerId, FirstName, LastName) VALUES (100, 'George', 'Washington')";const[rowCount]=awaittx.runUpdate(sql);console.log(`${rowCount} record inserted.`);awaittx.commit();});}catch(err){console.error('ERROR:',err);}finally{awaitdatabase.close();}}executeTransactionWithTimeout();

Python

# instance_id = "your-spanner-instance"# database_id = "your-spanner-db-id"spanner_client=spanner.Client()instance=spanner_client.instance(instance_id)database=instance.database(database_id)defread_then_write(transaction):# Read records.results=transaction.execute_sql("SELECT SingerId, FirstName, LastName FROM Singers ORDER BY LastName, FirstName")forresultinresults:print("SingerId:{}, FirstName:{}, LastName:{}".format(*result))# Insert a record.row_ct=transaction.execute_update("INSERT INTO Singers (SingerId, FirstName, LastName) "" VALUES (100, 'George', 'Washington')")print("{} record(s) inserted.".format(row_ct))# configure transaction timeout to 60 secondsdatabase.run_in_transaction(read_then_write,timeout_secs=60)

Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2025-12-17 UTC.