簡體   English   中英

ndb 事務中的數據存儲實體讀取(keys_only)

[英]Datastore Entity read (keys_only) inside ndb transactions

我有一個關於在 ndb 事務中讀取數據存儲實體的問題。

我知道當我們在 ndb 事務中讀取實體時,該特定實體被鎖定,並且沒有其他線程可以放置/更新/寫入同一實體,因為這會導致爭用錯誤。 這完全有道理。

但是,當我們在事務中只讀取實體的鍵而不是整個實體本身時會發生什么? 這可以通過在 ndb.query().fetch()中將 keys_only標志傳遞為 True 來完成。在這種情況下,實體會再次被鎖定嗎?

事務鎖數據存儲文檔說:

讀寫事務使用讀/寫鎖來強制隔離和可串行化。

並且它沒有提到任何在交易期間使用keys_only情況。 所以我認為這同樣適用於那種情況,如果你認為你仍然在閱讀,這確實是有道理的,你只是忽略了數據。

話雖如此,也許這可以改進到 Datastore 中,甚至可以在文檔中明確說明。 如果您願意,您可以考慮打開一個功能請求,讓 Google 通過點擊此鏈接來實施該功能。

一般來說,最好根據它們的保證——可串行化——而不是它們的實現細節——在這種情況下,讀/寫鎖來考慮事務。 實現細節(查詢的執行方式、鎖定粒度、鎖定的確切內容等)可能隨時更改,而保證不會更改。

對於這個特定問題,並假設 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM