環境:nodejs,firebase -admin,firestore。
資料庫結構(空格):

資料庫結構(用戶):

創建新空間(示例):
// init data
const userId = "someUserId";
// Create new space
const spaceRef = await db.collection("spaces").add({ name: "SomeName" });
// Get spaceId
spaceId = spaceRef.id;
// Get user Doc for upate their spaces
const userRef = await db.collection("users").doc(userId);
// Add "spaceId" to user spaces list
userRef.collection("spaces").doc(spaceId).set({ some: "data" });
// Create collection "members" in new space with "userId"
spaceRef.collection("members").doc(userId).set({role: "OWNER"})
問題:我想在單個runTransaction 中執行此代碼,但是當我看到事務僅支持一次讀取和多次更新時,這不適合我,因為我spaceId在執行代碼期間得到了我需要的。
為什么我要使用事務:在我的資料結構中,需要創建空間和這個空間的ID在用戶上的存在之間的關系。如果我們假設在這段代碼的執行程序中發生了錯誤,例如創建了空間,但是在用戶組態檔中沒有添加這個空間,那么這將是我的資料庫結構中的一個致命問題。
與其他資料庫類似,事務解決了這個問題,但我不知道如何用 firestore 來解決這個問題。
也許您知道在這種情況下保護自己免受一致資料影響的更好方法?
uj5u.com熱心網友回復:
實際上,您不需要交易,因為您沒有閱讀檔案。
隨著db.collection("users").doc(userId);你實際上沒有閱讀檔案,只呼叫“本地”的doc()方法來創建一個DocumentReference。此方法不是異步的,因此您不需要使用await. 要閱讀檔案,您將使用異步get()方法。
因此,使用批量寫入,將所有掛起的寫入操作原子地提交到資料庫,可以解決問題:
const userId = 'someUserId';
const userRef = db.collection('users').doc(userId);
const spaceRef = firestore.collection('spaces').doc();
const spaceId = spaceRef.id;
const writeBatch = firestore.batch();
writeBatch.set(spaceRef, { name: "SomeName" });
writeBatch.set(userRef.collection("spaces").doc(spaceId), { some: "data" });
writeBatch.set(spaceRef.collection("members").doc(userId), {role: "OWNER"});
await writeBatch.commit();
您應該將此代碼包含在一個try/catch塊中,如果批量提交失敗,您將能夠在catch塊中處理這種情況,因為知道沒有提交任何寫入。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/333912.html
標籤:javascript 节点.js 火力基地 谷歌云firestore
