2015-07-20 55 views
6

我在下面发现了一些讨论此场景的线索。Firebase:在单笔交易中更新多个对象

但是仍然在努力寻找,如果有任何建议的数据结构设计这一点。 我看到一个多写库firebase-multi-write其中说你可能不需要在大多数情况下。

但是我觉得我需要这个,我的方案是:3个用户

/users/A : {credit:20} 

/users/B : {credit:3} 

/users/C : {credit:10} 

而且每个用户可以相互都在同一时间偷学分,

  • 一来自B学分的抢断看起来像{21,2}
  • B从C学分的抢断看起来像{3,9}
  • 来自A学分的C抢断看起来像{11,2 0}

现在我需要更新每个用户的信用来保持这种一致性,以便每个窃取操作本质上是原子性的。

什么是最好的方式来处理这种情况,同时保持数据的完整性Java

+1

你的第一个连接线程会谈有关的另一种方法(事件采购 - http://martinfowler.com/eaaDev/ EventSourcing.html)。您会编写一个捕获所有三个盗窃事件的事件,然后当您需要查找当前的贷方余额时,您可以加载初始状态(可能为0个贷记),然后播放事件历史记录,直到最终状态结束。积分 - 你有所有“抢断”的历史。有没有理由不接受? –

+0

谢谢,我提到的场景是我设想的工作流程的简化版本。这是简单的游戏应用程序的一部分,其中A抢断形式B,并在下一刻B抢断它与C和D球员的混合。所以它对于一个简单的原子更新只是太多的计算? – duskandawn

+0

我不知道你的场景是否知道原子操作是否会起作用 - 但是你描述的对我来说听起来不像是原子操作。如果A从B拿走然后“在下一个时刻”B将其偷回......那不是原子的。这是发生在彼此附近的两种截然不同的操作。 –

回答

3

2015年9月,Firebase开发者发布了new version

在这个版本中,你现在可以做到这一点在单个原子更新这两个位置:

Firebase ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com"); 
// Generate a new push ID for the new post 

Firebase newPostRef = ref.child("posts").push(); 
String newPostKey = newPostRef.getKey(); 

// Create the data we want to update 
Map newPost = new HashMap(); 
newPost.put("title", "New Post"); 
newPost.put("content", "Here is my new post!"); 

Map updatedUserData = new HashMap(); 
updatedUserData.put("users/posts/" + newPostKey, true); 
updatedUserData.put("posts/" + newPostKey, newPost); 

// Do a deep-path update 
ref.updateChildren(updatedUserData, new Firebase.CompletionListener() { 
    @Override 
    public void onComplete(FirebaseError firebaseError, Firebase firebase) { 
     if (firebaseError != null) { 
      System.out.println("Error updating data: " + firebaseError.getMessage()); 
     } 
    } 
});