Skip to content

We should not retry ABORTED transactions #1230

Closed

Description

@mziccard

In datastore we have ABORTED among retryable exceptions. This causes commit requests failed due to contention to be retried. Retrying an ABORTED transaction always fails with INVALID ARGUMENT error.

I suggest we never retry ABORTED. \cc @aozarov @ajkannan

Activity

  1. ajkannan commented on Sep 9, 2016

    @ajkannan

    Just to make sure I understand, when you said "Retrying an aborted transaction", you meant any Datastore rpc rather than committing a Datastore Transaction specifically, correct? Since the Datastore docs seem to suggest ABORTED is a retryable exception, I wouldn't necessarily expect the non-retryable error code INVALID_ARGUMENT to be returned when retrying (especially if the original error is due to contention). Is there any more information included in the INVALID ARGUMENT error message?

  2. aozarov commented on Sep 9, 2016

    @aozarov
    Contributor

    I agree with @ajkannan. AFAIK contention should not invalidate a transaction.
    /cc @eddavisson is that no longer (or never was) the case?

  3. eddavisson commented on Sep 9, 2016

    @eddavisson

    Contention has to invalidate a transaction, otherwise we can't guarantee serializability. In this scenario:

    t1 = datastore.beginTransaction()
    entity = t1.lookup(key)
    datastore.commit(entity.set('foo', 'd')) // not in transaction
    t1.commit(entity.set('foo', 't'))
    

    The commit can't be retried because the value returned by the lookup call was invalidated by the commit from outside the transaction. You have to start over.

    You could, however, retry a NON_TRANSACTIONAL commit (i.e. a blind write) if it fails with ABORTED.

    This sounds like a documentation bug to me?

  4. mziccard commented on Sep 9, 2016

    @mziccard
    ContributorAuthor

    This sounds like a documentation bug to me?

    Yes, docs should make clear that ABORTED commit requests should only be retried when they are NON_TRANSACTIONAL. Otherwise, the whole transaction should be retried.

  5. aozarov commented on Sep 9, 2016

    @aozarov
    Contributor

    Ah, right. so I guess ABORTED is like getting java.util.ConcurrentModificationException in the AE datastore Java API. @eddavisson why/in-what-case would you propagate such an error for non transnational commits? Indeed, doc is not clear and I think should make the distinction between transnational to non transnational when it comes to its retry suggestion.

  6. eddavisson commented on Sep 9, 2016

    @eddavisson

    The NON_TRANSACTIONAL commit still does a read/write "transaction" internally. If an entity group changes between the read and write, then the commit fails with ABORTED. Entity groups that are seeing a lot of contention can still hit this.

    One final note about the retryability of TRANSACTIONAL commits: you can retry the entire operation (starting with the beginTransaction() call). That's what, for example, the @ndb.transactional decorator does (https://cloud.google.com/appengine/docs/python/ndb/transactions).

    I'll work on getting our documentation fixed.

  7. WalterHub commented on Sep 9, 2016

    @WalterHub
    Contributor

    Thank you for the doc feedback. A fix has been published to https://cloud.google.com/datastore/docs/concepts/errors.

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

Metadata

Metadata

Assignees

Labels

api: datastoreIssues related to the Datastore API.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions