You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
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?
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.
Yes, docs should make clear that ABORTEDcommit requests should only be retried when they are NON_TRANSACTIONAL. Otherwise, the whole transaction should be retried.
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.
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).
Activity
ajkannan commentedon Sep 9, 2016
Just to make sure I understand, when you said "Retrying an aborted transaction", you meant any Datastore rpc rather than committing a Datastore
Transactionspecifically, correct? Since the Datastore docs seem to suggestABORTEDis a retryable exception, I wouldn't necessarily expect the non-retryable error codeINVALID_ARGUMENTto be returned when retrying (especially if the original error is due to contention). Is there any more information included in theINVALID ARGUMENTerror message?aozarov commentedon Sep 9, 2016
I agree with @ajkannan. AFAIK contention should not invalidate a transaction.
/cc @eddavisson is that no longer (or never was) the case?
eddavisson commentedon Sep 9, 2016
Contention has to invalidate a transaction, otherwise we can't guarantee serializability. In this scenario:
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_TRANSACTIONALcommit (i.e. a blind write) if it fails withABORTED.This sounds like a documentation bug to me?
mziccard commentedon Sep 9, 2016
Yes, docs should make clear that
ABORTEDcommitrequests should only be retried when they areNON_TRANSACTIONAL. Otherwise, the whole transaction should be retried.aozarov commentedon Sep 9, 2016
Ah, right. so I guess
ABORTEDis like gettingjava.util.ConcurrentModificationExceptionin 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.eddavisson commentedon Sep 9, 2016
The
NON_TRANSACTIONALcommit still does a read/write "transaction" internally. If an entity group changes between the read and write, then the commit fails withABORTED. Entity groups that are seeing a lot of contention can still hit this.One final note about the retryability of
TRANSACTIONALcommits: you can retry the entire operation (starting with thebeginTransaction()call). That's what, for example, the@ndb.transactionaldecorator does (https://cloud.google.com/appengine/docs/python/ndb/transactions).I'll work on getting our documentation fixed.
WalterHub commentedon Sep 9, 2016
Thank you for the doc feedback. A fix has been published to https://cloud.google.com/datastore/docs/concepts/errors.
chore(main): release 3.4.0 (googleapis#1232)
chore(main): release 2.3.8-SNAPSHOT (#1230)
deps: update dependency org.junit.vintage:junit-vintage-engine to v5.…
chore(main): release 2.17.6 (#1232)
chore(main): release 1.19.1-SNAPSHOT (#1230)
chore(main): release 1.19.1-SNAPSHOT (#1230)
chore(deps): update dependency com.google.cloud:google-cloud-spanner-…
chore(deps): update dependency com.google.cloud:libraries-bom to v26.…
chore(deps): update dependency com.google.cloud:libraries-bom to v26.…
chore(deps): update dependency com.google.cloud:google-cloud-pubsub t…
chore(deps): update dependency com.google.cloud:google-cloud-pubsub t…
build(deps): update dependency com.google.cloud:google-cloud-shared-c…