Skip to content
This repository was archived by the owner on Jun 8, 2026. It is now read-only.
This repository was archived by the owner on Jun 8, 2026. It is now read-only.

database.batch does not retry aborted transactions #1133

Closed

Description

@olavloite

The standard example for writing data with mutations uses database.batch: https://cloud.google.com/spanner/docs/getting-started/python#write-data-with-mutations

database.batch however does not automatically retry the transaction if it is aborted by Spanner. This causes errors if you try to use this method to insert a large amount of data, or if there are lock contentions on the data that you insert.

Either:

  1. The sample(s) should be updated to show how to use run_in_transaction to use mutations.
  2. And/or: database.batch should also automatically retry aborted transactions.

Activity

  1. added
    type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.
    priority: p1Important issue which blocks shipping the next release. Will be fixed prior to next release.
    on Apr 26, 2024
  2. added
    priority: p2Moderately-important priority. Fix may not be included in next release.
    and removed
    priority: p1Important issue which blocks shipping the next release. Will be fixed prior to next release.
    on Sep 1, 2024
  3. aakashanandg commented on Dec 12, 2024

    @aakashanandg
    Contributor

    After reviewing the database.batch API, we found that commit calls within a batch are automatically retried, with a default retry count of 5. You can refer to this line in the code for more details: link. The batch.insert API simply appends values to the mutations list, and these values are persisted in the database when the commit API is called on the Spanner client. This behavior is consistent across all Batch APIs defined here: link.

    It's important to note that retries are only triggered in the case of an InternalServerError exception. For more information, refer to: link. However, I don't believe these retries are triggered if an Aborted exception occurs during a transaction execution.

  4. olavloite commented on Dec 12, 2024

    @olavloite
    ContributorAuthor

    Yeah, this bug is specifically for Aborted errors. If the transaction is aborted by Spanner (meaning: Spanner returns an error with error code Aborted), then the transaction should be retried. The retry mechanism should be the same as for run_in_transaction; It should do a back-off and retry, using the back-off value that is included in the Aborted error. There should not be a maximum number of retries, instead it should stop retrying if the deadline has been exceeded.

  5. aakashanandg commented on Dec 12, 2024

    @aakashanandg
    Contributor

    I understand. The run_in_transaction method currently evaluates the deadline value using the keyword arguments, as defined here: link. In my opinion, it's the client's responsibility to pass the timeout (in seconds) as part of the keyword arguments for the transaction. For our use case, how should we handle the evaluation of the deadline value? Should we define a default timeout for all mutation operations and use that to set the deadline, or is there another approach we should consider.

  6. aakashanandg commented on Jan 2, 2025

    @aakashanandg
    Contributor

    PR: #1279

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

api: spannerIssues related to the googleapis/python-spanner API.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