![](/img/trans.png)
[英]What's the equivalent of Entity.all(keys_only=True).fetch(20) in NDB?
[英]Datastore Entity read (keys_only) inside ndb transactions
我有一個關於在 ndb 事務中讀取數據存儲實體的問題。
我知道當我們在 ndb 事務中讀取實體時,該特定實體被鎖定,並且沒有其他線程可以放置/更新/寫入同一實體,因為這會導致爭用錯誤。 這完全有道理。
但是,當我們在事務中只讀取實體的鍵而不是整個實體本身時會發生什么? 這可以通過在 ndb.query().fetch()中將 keys_only標志傳遞為 True 來完成。在這種情況下,實體會再次被鎖定嗎?
一般來說,最好根據它們的保證——可串行化——而不是它們的實現細節——在這種情況下,讀/寫鎖來考慮事務。 實現細節(查詢的執行方式、鎖定粒度、鎖定的確切內容等)可能隨時更改,而保證不會更改。
對於這個特定問題,並假設 Firestore 當前在 Datastore 模式下實現:為了確保可序列化,事務 T1 中的僅鍵查詢會鎖定查詢檢查的索引條目的范圍。 如果這樣的查詢返回實體 E 的鍵 K,那么在不同事務 T2 中刪除 E 的嘗試必須刪除 E 的所有索引條目,包括查詢鎖定范圍內的索引條目。 所以在這個例子中,T1 和 T2 需要相同的鎖,兩個事務之一將被延遲或中止。
請注意,T2 還有其他方式與 T1 發生沖突:它還可以創建一個新實體來匹配 T1 的查詢(這將需要在 T1 的查詢鎖定的范圍內寫入索引條目)。
最后,如果 T2 以某種方式更新(而不是刪除)E,該方式確實需要對 T1 查詢檢查的范圍內的索引條目進行任何更新(例如,如果查詢類似於 'select * from X where a = 5'並且對 E 的更新不會改變它的“a”屬性的值)那么 T1 和 T2 不會沖突(這是一種優化 - 如果這兩個事務確實發生沖突,行為仍然是正確的,實際上對於“Datastore Native”數據庫,它們可能會發生沖突)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.