24

I understand that Firebase transactions enable the atomic update of some value, given its old value and new value

But given that Firebase is a realtime database, I assume, one must use transactions only sparingly and not in 'realtime features'

here's an example:

  1. I understand that if you are performing some mathematical operation on a value (adding 'likes' or equivalent), it makes sense to use transaction

  2. I dont understand if it makes sense to use transactions in the following use case: Say a text field can be updated by any number of users, and we are interested in all the updates, as they occur in real time. Does firebase recommend we use transaction in this case? Or is the final 'persist operation' that occurs on the value, only limited to a single 'persist operation' per timestamp granularity of the Firebase server clock?

Further is it guaranteed that the events will be delivered in the order of which the final values were persisted?

7hacker
  • 1,928
  • 3
  • 19
  • 32

1 Answers1

24

Whenever you use transactions on a database, you sacrifice some of your scalability in order to have a stronger data consistency guarantee. Transactions on the Firebase Database are no different, except maybe that developers tend to use Firebase in more highly concurrent situations.

With any transactional system: the key to keeping the system scalable is to minimize the number of clients contending to update the same data. In the case of Firebase, you'd accomplish that by running your transaction as low as possible in your JSON tree. I.e. a counter is a example of something that could work well under a transaction.

For larger pieces of data, such as your text editing example, using a transaction will not scale well. For such use-cases it is better to find a way to avoid the conflict altogether. Quite often this boils down to storing the delta that each user is making, instead of storing the updated state. A great example of this is in the Firepad example, which uses operational transform to create a highly concurrent collaborative editor on top of the Firebase Database.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Yes I dont intend to use transactions either. here's an example. Assume a "Comment" system. I can go ahead and store all comments in a "comments" root node with a unique push key + some attributes. This root can grow large and if I'd like to get a sorted list I'd send a query with some sort parameter (on timestamp). If I have another node : CommentLatest, which stores the unique push key of the latest comment. So each client performs two write: A write to the "Comment" tree with a unique push key and an update to the commentlatest tree with latest=unique push key it just used. Does this scale? – 7hacker Jun 30 '16 at 00:54
  • (continued) and is there a possibility of corruption at the CommentLatest node if there are multiple clients update the commentLatest node? – 7hacker Jun 30 '16 at 00:55
  • 1
    If you're worried about contention of updating the `latestCommentId` value, you might be optimizing prematurely. Overwriting with older date can be prevented by including the timestamp as the value of `latestCommentId` and then rejecting of the timestamp is older than what is currently there. But note that we went from an incredibly broad question to a very detailed use-case here. You might want to first spend some more time working with Firebase transactions and then ask a more concrete question with code and security rules. – Frank van Puffelen Jun 30 '16 at 01:17
  • @FrankvanPuffelen What is I want to update multiple paths in a single transaction? For example moving money from a user account to another? – Muhammad Hassan Nasr Dec 26 '16 at 14:17
  • @FrankvanPuffelen could you expand on << For larger pieces of data, such as your text editing example, using a transaction will not scale well. >>. Why is that the case ? – Ced Aug 22 '17 at 16:11
  • 1
    In many use-case the chances of concurrent modification go up with the size of the data. And concurrent modification leads to contention (conflicting updates), which leads to retries, which limits concurrency and thus scalability. – Frank van Puffelen Aug 22 '17 at 22:22