Search code examples
firebasegoogle-cloud-firestoretransactionspessimistic-locking

Conflict handling for write operations during pessimistic lock transaction in Firestore


I have a question about server-side pessimistic locking transactions provided by the backend SDKs in Firestore.

Consider the following tasks:

Transaction A
Transaction B
Transaction C
normal write C

While Transaction B is implementing the lock for Transaction A, Transaction C can read from Transaction A but cannot write to it.

In that case, Transaction C waits until the lock on Transaction A is released, and then gets its lock and performs read and write again.

I understand the basic behavior of Firebase’s server-side pessimistic lock transactions as described above.

So here’s my question.

If we consider Normal action C as a “non-transactional” normal write on the client-side, if normal action C performs the part of Transaction C in the above situation, will the write to Transaction A by normal action C succeed? Or will it fail?

For example, there is code that performs transaction on a talkuser document within a user collecton.

return db.runTransaction(async (transaction) => {
                    
const talkuserFieldsRef = db.collection("user").doc(data.talkuserUid);
const talkuserFieldsSnapshot = await transaction.get(talkuserFieldsRef);
        
transaction.update(talkuserFieldsRef, {
    “talkuser_status": true,}});

In the case where write operations from other tasks are performed on the talkuser document, which is not transaction method:

・The writes from other tasks take precedence, and the transaction fails.

・The lock on the transaction takes precedence, and the writes from other tasks fail.

Which of these will occur?


Solution

  • From the documentation, emphasis mine:

    In the server client libraries, transactions place locks on the documents they read. A transaction's lock on a document blocks other transactions, batched writes, and non-transactional writes from changing that document.

    A transaction blocks all non-transactional writes. In that sense, you can think of a non-transactions write of a single document as a transaction that only writes one document, so it's treated like any other transaction in terms of its behavior under contention. The write doesn't fail, it just happens some time later when no locks are stopping it.