Skip to content

RunTransaction doesn't work with only reads #736

@radhus

Description

@radhus

We use Postgres dialect and the RunTransaction function to get retries for our transactions, both read and write. We happened to still run v1.15.0, and when upgrading this dependency it turns out that this doesn't work for read transactions since version v1.17.0.

I adapted the examples/postgres test to demonstrate the issue:

func helloWorldFromPostgreSQL(projectId, instanceId, databaseId string) error {
	ctx := context.Background()
	db, err := sql.Open("spanner", fmt.Sprintf("projects/%s/instances/%s/databases/%s", projectId, instanceId, databaseId))
	if err != nil {
		return fmt.Errorf("failed to open database connection: %v", err)
	}
	defer db.Close()

	err = spannerdriver.RunTransaction(
		ctx,
		db,
		&sql.TxOptions{ReadOnly: true},
		func(ctx context.Context, tx *sql.Tx) error {
			rows, err := tx.QueryContext(ctx, "SELECT $1::varchar as message", "Hello World from Spanner PostgreSQL")
			if err != nil {
				return fmt.Errorf("failed to execute query: %v", err)
			}
			defer rows.Close()

			var msg string
			for rows.Next() {
				if err := rows.Scan(&msg); err != nil {
					return fmt.Errorf("failed to scan row values: %v", err)
				}
				fmt.Printf("%s\n", msg)
			}
			if err := rows.Err(); err != nil {
				return fmt.Errorf("failed to execute query: %v", err)
			}
			return nil
		},
	)
	if err != nil {
		return fmt.Errorf("transaction failed: %v", err)
	}
	return nil
}

This test passes on v1.15.0:

Hello World from Spanner PostgreSQL

But on later versions, it fails with:

2026/01/21 16:26:21 transaction failed: spanner: code = "FailedPrecondition", desc = "this connection has not executed a read/write transaction that committed successfully"

I bisected the issue and it pinpointed first bad commit 463bb09 (PR #491) - something that was included to fix my own request in #488 🙈. Sorry for not testing it earlier!

Do you think we should keep using RunTransaction for read transactions, or should we use another pattern?

Thanks!

Environment details

  • Programming language: Go
  • OS: macOS
  • Language runtime version: Go 1.25.5
  • Package version: From v1.18.0 and to latest

Metadata

Metadata

Assignees

No one assigned

    Labels

    priority: p2Moderately-important priority. Fix may not be included in next release.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions