了解Firebase中的冲突解决 [英] Understanding conflict resolution in firebase

查看:63
本文介绍了了解Firebase中的冲突解决的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正试图了解解决冲突在Firebase中的工作方式,对此我需要一些帮助.

I'm trying to understand the way the conflict resolution works in firebase for which I need some help.

假设我已将json对象保存在firebase的节点中实时:

Assuming that I've json object saved in a node in firebase realtime:

{
    "shape": "rectangle",
    "stroke": 10, 
    "color": "black"
}

我已经定义了一个测试页面,该页面可以读取并显示此数据,还可以实时监听具有key的节点上发生的更改.我添加了一项条款来更新数据,最终仅更新了特定的键值.

I've defined a test page which reads this data and displays and also listens to the changes happening on node with key in realtime. I've added a provision to update the data which eventually updates the specific key value alone.

使用案例样本

client 1 - loads the page
    data - {"shape": "rectangle", "stroke": 10, "color": "black"}
client 2 - loads the page 
    data - {"shape": "rectangle", "stroke": 10, "color": "black"}

client 2 goes offline
client 2 updates stroke value to 20 
    data - {"shape": "rectangle", "stroke": 20, "color": "black"}
* data is yet to sync to the server

client 1 makes a change after client 2 has already done with its changes and changes stroke to 5
    data - {"shape": "rectangle", "stroke": 5, "color": "black"}
* data gets synced to the server immediately


client 2 comes online and pushes its changes and overrides the changes made by client 1
    data - {"shape": "rectangle", "stroke": 20, "color": "black"}

理想情况下,由于客户端1的更改时间比客户端2的更改晚,因此客户端1的更改应在客户端2的数据同步后保留.

Ideally since the client 1 made the change at a later point of time than client 2 the client 1 changes should be retained when client 2 data gets synced.

如果有人可以向我提出解决Firebase中此类冲突的方法(可能是通过定义一些规则和一些额外的逻辑),我将感到非常高兴.

I would be very glad if somebody can suggest me a way to such type of conflict resolution in firebase(may be by defining some rules and some extra logic).

推荐答案

使用您当前的代码,预期的行为确实是最后一次写操作获胜.

With your current code, the expected behavior is indeed that the last write wins.

还有两个选择:

  1. 使用事务来检测数据已被更改,然后重试.
  2. 通过使用一种将写操作与每个客户端分开的数据结构,可以完全避免冲突.

让我们依次看看.

使用交易是解决此问题的最常用方法.在Firebase中使用事务时,客户端会将比较并设置"操作发送到服务器.这是一种类型的指令:如果当前值为A,则将其设置为B".在您的情况下,这意味着第二次写操作检测到笔划已经更改,因此将重试.

Using transactions is the most common way around this problem. When you use a transaction in Firebase, the client sends a "compare and set" operation to the server. This is an instruction of the type: "if the current value is A, set it to B". In your scenario that means that the second write detects that the stroke has already changed, so it gets a retry.

要了解有关交易的更多信息,请参阅 Firebase文档,我在这里回答了它们的工作原理.

To learn more about transactions have a look at the Firebase documentation, and at my answer here about how they work.

这听起来像是一个很好的解决方案,但不幸的是,它确实会影响代码的可伸缩性.尝试修改相同数据的用户越多,事务重试的可能性就越大.这就是为什么最好考虑是否可以完全避免冲突.

This may sound like a great solution, but it does unfortunately affect the scalability of your code. The more users are trying to modify the same data, the more likely the transaction has to retry. That's why it's always good to consider if the conflict can be avoided altogether.

预防冲突是目前最好的解决冲突的策略.通过防止冲突,您不必解决冲突,这意味着您不必编写代码来解决冲突,这意味着您的应用程序可以更好/更广泛地扩展.

Preventing conflicts is the best conflict resolution strategy out there. By preventing conflicts, you never have to resolve them, which means you never have to write code to resolve conflicts, which means that your application will scale a lot better/farther.

为防止冲突,您将需要寻找一种数据结构,其中用户始终在其唯一位置写入数据.在您的用例中,您可以让客户端将其更新操作"写入更新队列,而不是让每个客户端都更新行程.例如:

To prevent conflicts, you'll want to look for a data structure where your users are always writing to unique locations. In your use case, instead of having each client update the stroke, you could instead have the client write their "update action" to a queue of updates. For example:

shapes
  shapeid1
    pushid1: {"shape": "rectangle", "stroke": 10, "color": "black"} /* initial data */
    pushid2: { "stroke": 5 } /* first update */
    pushid3: { "stroke": 20 } /* second update */

在此数据结构中,没有人会覆盖其他人的数据(在安全规则中易于执行的操作).每个人都只是在形状上添加新的更新(使用 ref.push(),它会按时间顺序生成唯一的位置).

In this data structure, nobody is overwriting anyone else's data (something that is easy to enforce in security rules). Everyone is just appending new updates to the shape (using ref.push(), which generates unique locations in chronological order).

要获取形状的当前数据,每个客户端将需要读取该形状的所有更新并在客户端上重新计算它们.对于大多数用例,我已经看到这是一个简单的操作,但是如果不是这样的话:让Cloud Function计算状态的定期快照非常容易.

To get the current data for a shape, each client will need to read all updates for that shape and recalculate them on the client. For most use-cases I've seen that's a simple operation, but if not: it is quite easy to have a Cloud Function calculate a periodic snapshot of the state.

这篇关于了解Firebase中的冲突解决的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆