Configure statement timeout

This page describes how to set a timeout for a single statement execution using the Spanner client libraries. This can be used to override the default timeout configuration of the client library. The statement fails with a DEADLINE_EXCEEDED error if the statement cannot finish within the given timeout value.

These samples show how to set a timeout for a single statement execution in the Cloud Spanner client library.

Go


import(
"context"
"fmt"
"io"
"time"
"cloud.google.com/go/spanner"
"google.golang.org/grpc/codes"
)
funcsetStatementTimeout(wio.Writer,dbstring)error{
client,err:=spanner.NewClient(context.Background(),db)
iferr!=nil{
returnerr
}
deferclient.Close()
_,err=client.ReadWriteTransaction(context.Background(),
func(ctxcontext.Context,txn*spanner.ReadWriteTransaction)error{
// Create a context with a 60-second timeout and apply this timeout to the insert statement.
ctxWithTimeout,cancel:=context.WithTimeout(context.Background(),60*time.Second)
defercancel()
stmt:=spanner.Statement {
SQL:`INSERT Singers (SingerId, FirstName, LastName)
					VALUES (39, 'George', 'Washington')`,
}
rowCount,err:=txn.Update(ctxWithTimeout,stmt)
// Get the error code from the error. This function returns codes.OK if err == nil.
code:=spanner.ErrCode (err)
ifcode==codes.DeadlineExceeded{
fmt.Fprintf(w,"Insert statement timed out.\n")
}elseifcode==codes.OK{
fmt.Fprintf(w,"%d record(s) inserted.\n",rowCount)
}else{
fmt.Fprintf(w,"Insert statement failed with error %v\n",err)
}
returnerr
})
iferr!=nil{
returnerr
}
returnnil
}

Java


staticvoidexecuteSqlWithTimeout(){
// TODO(developer): Replace these variables before running the sample.
StringprojectId="my-project";
StringinstanceId="my-instance";
StringdatabaseId="my-database";
try(Spannerspanner=
SpannerOptions.newBuilder().setProjectId(projectId).build().getService()){
DatabaseClientclient=
spanner.getDatabaseClient(DatabaseId.of(projectId,instanceId,databaseId));
executeSqlWithTimeout(client);
}
}
staticvoidexecuteSqlWithTimeout(DatabaseClientclient){
CallContextConfiguratorconfigurator=newCallContextConfigurator(){
public<ReqT,RespT>ApiCallContextconfigure(ApiCallContextcontext,ReqTrequest,
MethodDescriptor<ReqT,RespT>method){
// DML uses the ExecuteSql RPC.
if(method==SpannerGrpc.getExecuteSqlMethod()){
// NOTE: You can use a GrpcCallContext to set a custom timeout for a single RPC
// invocation. This timeout can however ONLY BE SHORTER than the default timeout
// for the RPC. If you set a timeout that is longer than the default timeout, then
// the default timeout will be used.
returnGrpcCallContext.createDefault()
.withCallOptions(CallOptions.DEFAULT.withDeadlineAfter(60L,TimeUnit.SECONDS));
}
// Return null to indicate that the default should be used for other methods.
returnnull;
}
};
// Create a context that uses the custom call configuration.
Contextcontext=
Context.current().withValue(SpannerOptions.CALL_CONTEXT_CONFIGURATOR_KEY,configurator);
// Run the transaction in the custom context.
context.run(()->
client.readWriteTransaction().<long[]>run(transaction->{
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 library
const{Spanner}=require('@google-cloud/spanner');
// Creates a client
constspanner=newSpanner ({
projectId:projectId,
});
asyncfunctionexecuteSqlWithTimeout(){
// Gets a reference to a Cloud Spanner instance and database.
constinstance=spanner.instance(instanceId);
constdatabase=instance.database(databaseId);
try{
awaitdatabase.runTransactionAsync (asynctx=>{
// NOTE: You can use gaxOptions to set a custom timeout for a single RPC
// invocation. This timeout can however ONLY BE SHORTER than the default timeout
// for the RPC. If you set a timeout that is longer than the default timeout, then
// the default timeout will be used.
constquery={
sql:"INSERT INTO Singers (SingerId, FirstName, LastName) VALUES (110, 'George', 'Washington')",
gaxOptions:{
timeout:60000,// 60 seconds timeout
},
};
constresults=awaittx.run(query);
console.log(`${results[1].rowCountExact} record inserted.`);
awaittx.commit();
});
}catch(err){
console.error('ERROR:',err);
}finally{
awaitdatabase.close();
}
}
executeSqlWithTimeout();

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)
defwrite(transaction):
 # Insert a record and configure the statement timeout to 60 seconds
 # This timeout can however ONLY BE SHORTER than the default timeout
 # for the RPC. If you set a timeout that is longer than the default timeout,
 # then the default timeout will be used.
 row_ct = transaction.execute_update(
 "INSERT INTO Singers (SingerId, FirstName, LastName) "
 " VALUES (110, 'George', 'Washington')",
 timeout=60,
 )
 print("{} record(s) inserted.".format(row_ct))
database.run_in_transaction(write)

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

Last updated 2025年10月14日 UTC.