Reputation: 508
I am using Firestore as a database in a Cloud Run infrastructure. The input data rate is considerably high, so in order to compensate for the delay and to get the latest data, I am using Firestore transaction for one of the fields in the Firestore document.
Basically, there is a possibility that N number of users try to access the same document and update it, Firestore transaction has been used in order to maintain the consistency.
And also along with this Transaction, there is one Normal Firestore update, which is done by a separate endpoint.
Transaction function
transactionFunction: async function(dataRef, userIdentifier) {
try {
const transactionOp = await app.db.runTransaction(async (t) => {
let returnData;
const doc = await t.get(dataRef);
let status = doc.data().status;
if (status == "one") {
throw "one";
} else {
returnData = GetUpdate();
if (returnData == "two") {
await t.update("status" : "one");
let return1 = {};
return1["currentStatus"] = "not-one";
return return1;
} else {
let return2 = {};
return2["currentStatus"] = "not-one";
}
}
return transactionOp;
}
} catch (err) {
let returnData = {};
returnData["currentStatus"] = "one";
return returnData;
}
}
Normal Update:
NormalUpdate: async function (app, dataRef) {
try {
await dataRef.update({
status: "not-one",
});
} catch (err) {
console("NormalUpdate : ", err);
}
},
When I run the above transaction with a high input data rate, I see below errors:
Error: 10 ABORTED: Too much contention on these documents. Please try again.
And
Error: 10 ABORTED: Aborted due to cross-transaction contention. This occurs when multiple transactions attempt to access the same data, requiring Firestore to abort at least one in order to enforce serializability.
I have 2 questions:
Does the transaction gets terminated in both the cases given above? As per the documentation here transaction gets terminated only for Error: 10 ABORTED: Too much contention on these documents. Please try again.
. However even in the second error, the catch block is called, so I think it terminates the transaction, kindly correct me my understanding is wrong here.
Does the parallel requests increase the data contention even if they are not actually writing/updating to Firestore? For example, one transaction (transaction-b) may have to retry as there is a change in the field value due to another transaction (transaction-a). Whether the transaction-b is accounted for the contention here, as it is not writing any data to the Firestore.
What is the difference between error a
and b
, in terms of impact on the data update?
Upvotes: 3
Views: 3611
Reputation: 182
1.) As per the documentation you have linked, the failing transaction gets aborted (there is at least one that effectively goes through), this isn't just for 2 transactions but can also be for more as seems to be the case.
1.a) It terminates at least one of the transactions, yes.
2.) I believe it does, given the "1 write per second per single document" abortion condition
3.a) One transaction stopped retrying because it did not manage to submit it's change in over 5 tries (might be more, last I checked it was 5 tries).
3.b) Two transactions tried at the same time, they can still retry (and likely will) but Firestore may choose to fail the transaction completely, so they will either retry or be removed so that they no longer cause conflict.
Upvotes: 1