2012-08-16 91 views
2

我在我的ZODB上運行並行寫入請求。我的ZODB中有多個BTree實例。一旦服務器訪問這樣的BTree中的相同對象,我得到ConflictErrorIOBucket類。對於我所有的Django基礎類,我設置了_p_resolveconflict,但無法實現IOBucket,因爲它的基於C的類。ZODB中的衝突解決

我做了一個更深入的分析,但仍不明白爲什麼它會抱怨IOBucket類以及它寫入的內容。另外,解決這個問題的正確策略是什麼?

千謝謝任何幫助!

回答

1

IOBucketBTree的持久性結構的一部分;它試圖減少衝突錯誤,並儘可能地嘗試和解決衝突。

也就是說,衝突並不總是可以避免的,您應該重新開始您的交易。例如,在Zope中,如果提出ConflictError,整個請求將重新運行5次。衝突是ZODB處理兩個不同請求試圖改變完全相同的數據結構(希望很少)的場合的方式。

重新啓動您的交易意味着撥打transaction.begin()並再次應用相同的更改。 .begin()將獲取其他進程所做的任何更改,並且您的提交將基於新數據。

+0

親愛的我使用django_zodb,在那裏交易很早,我不會攔截它。我昨天發現的是,在更改數據存儲之後調用root._p_jar.sync()和transaction.savepoint之後,解決了衝突錯誤。儘管我沒有完全理解這個邏輯。它有意義還是我有點奇怪? – patroqueeet 2012-08-17 06:41:22

+0

另一個問題:所以建立一個能夠捕獲異常大約5次的loog是有意義的,然後等待幾個ms,然後重新執行一個完整的新事務? 如果是這樣的話。我記住,我的事務在服務器請求時開始,並在響應呈現時結束。這會過時嗎?因此,對於我非常安全的環境來說,複雜交易對zodb來說不是一個好方法?這些交易應該更像ACID? – patroqueeet 2012-08-17 06:44:24

+0

@patroqueeet:'_p_jar.sync()'表示加載最新的數據(這意味着你現在可以使用不一致的狀態)。 '保存點'只是一種方法,用於在提交時間之前刷新對磁盤的更改(釋放內存)。 – 2012-08-17 06:44:43