Firestore Transactions with Python
The documentation on writing firestore transactions with python is not especially extensive, so I figured I’d share what I learned when setting up transactions for my project Artifai.
My goal was to pull an item from a queue collection, but I needed to avoid the scenario where two threads pull items from the queue at the same time. Transactions are perfect for this because you can ensure that no two machines pull the same item off the queue.
In the case of a concurrent edit, Cloud Firestore runs the entire transaction again. For example, if a transaction reads documents and another client modifies any of those documents, Cloud Firestore retries the transaction. This feature ensures that the transaction runs on up-to-date and consistent data.
Here is how you create a transaction. Define a method with the
@firestore.transactional decorator that has parameters for a transaction and a query reference.
The goal of this transaction is to
- read the last document from the queue
- delete the document
- return the information the document was storing
If this transaction is in progress and the queue collection gets modified (by another thread pulling an item from the queue), it will restart the transaction; this ensures that no two threads will pull the same item off of the queue. If there are no items left on the queue, the method returns a dictionary with status set to 2 (to be handled later in the program).
Great! We have now defined a transaction. In order to execute it you can do the following:
We create our
queue_objects_ref, and then repeatedly try to execute the transaction in a
while True loop. If the transaction fails, it throws an error which gets caught by the try except statement. If it isn’t able to complete the transaction in 20 tries, it gives up and exits the program.
Hopefully this gives you an idea for how to build workflows with firestore transactions in python. Let me know if you have any comments or questions below!