Skip to content

Commit

Permalink
chore: disable internal retries when using runner
Browse files Browse the repository at this point in the history
  • Loading branch information
olavloite committed Nov 25, 2024
1 parent 110f758 commit 5a054ad
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 2 deletions.
10 changes: 9 additions & 1 deletion retry.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (

"cloud.google.com/go/spanner"
"github.com/googleapis/gax-go/v2"
spannerdriver "github.com/googleapis/go-sql-spanner"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"gorm.io/gorm"
Expand All @@ -30,8 +31,15 @@ import (
// RunTransaction executes a transaction on Spanner using the given
// gorm database, and retries the transaction if it is aborted by Spanner.
func RunTransaction(ctx context.Context, db *gorm.DB, fc func(tx *gorm.DB) error, opts ...*sql.TxOptions) error {
// Disable internal (checksum-based) retries on the Spanner database/SQL connection.
var opt *sql.TxOptions
// Note: gorm also only uses the first option, so it is safe to pick just the first element in the slice.
if len(opts) > 0 {
opt = opts[0]
}
opt.Isolation = spannerdriver.WithDisableRetryAborts(opt.Isolation)
for {
err := db.Transaction(fc, opts...)
err := db.Transaction(fc, opt)
if err == nil {
return nil
}
Expand Down
7 changes: 6 additions & 1 deletion spanner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,15 +260,20 @@ func TestRunTransaction(t *testing.T) {
server.TestSpanner.PutExecutionTime(testutil.MethodCommitTransaction, testutil.SimulatedExecutionTime{
Errors: []error{status.Error(codes.Aborted, "Aborted")},
})
attempts := 0
if err := RunTransaction(ctx, db, func(tx *gorm.DB) error {
attempts++
if err := tx.Create(&s).Error; err != nil {
return err
}
return nil
}, &sql.TxOptions{}); err != nil {
t.Fatal(err)
}
// Now verify that the insert was executed twice.
// Now verify that the insert was executed twice and that the function was called twice.
if g, w := attempts, 2; g != w {
t.Fatalf("attempts mismatch\n Got: %v\nWant: %v", g, w)
}
reqs = drainRequestsFromServer(server.TestSpanner)
execReqs = requestsOfType(reqs, reflect.TypeOf(&spannerpb.ExecuteSqlRequest{}))
insertReqs = filter(execReqs, insertSql)
Expand Down

0 comments on commit 5a054ad

Please sign in to comment.