2014-06-22 14 views
16

我和greenDAO一起去了,到目前爲止它的情況非常好。有一件事似乎並沒有被文檔或網站(或任何地方:()所涵蓋,它是如何處理線程安全的。是否有greenDAO線程安全最佳實踐?

我知道其他地方提到的基本知識,比如「使用單一的dao會話」(一般練習對於Android + SQLite),我很理解Java內存模型,庫內部甚至出現線程安全,或者至少是用這種意圖構建的,但我沒有見過這種內容:

greenDAO默認緩存實體這對於完全單線程的程序來說非常好 - 對於大多數用途來說透明和大規模的性能提升。但是,如果我例如loadAll()然後修改其中一個元素,我正在修改同一個對象global通過我的應用程序,可以使用。如果我在主線程上使用它(例如用於顯示),並且在後臺線程上更新數據庫(如果是正確的話),除非格外小心,否則存在明顯的線程問題。

greenDAO做了什麼「底層」防範常見的應用程序級線程問題嗎?例如,修改UI線程中的緩存實體,同時將其保存在後臺線程中(更好地希望它們不交織!特別是在修改列表時!)?除了一般的線程安全問題(即greenDAO期望並且可以很好地工作)之外,是否有任何「最佳實踐」來防範它們?或者,從多線程應用程序安全角度來看,整個緩存是致命的缺陷?

回答

1

我已經與greenDAO沒有經驗,但這裏的文檔: http://greendao-orm.com/documentation/queries/

說:

如果您在使用多線程查詢,則必須在查詢調用forCurrentThread()得到一個當前線程的查詢實例。從greenDAO 1.3開始,Query的對象實例綁定到它們自己的構建查詢的線程。這使您可以安全地在Query對象上設置參數,而其他線程不會產生干擾。如果其他線程嘗試在查詢上設置參數或執行綁定到另一個線程的查詢,則會引發異常。像這樣,你不需要一個同步語句。事實上,你應該避免鎖定,因爲如果併發事務使用相同的查詢對象,這可能會導致死鎖。

爲了完全避免這些潛在的死鎖,greenDAO 1.3引入了forCurrentThread()方法。這將返回Query的線程本地實例,這在當前線程中可以安全使用。每次調用forCurrentThread()時,都會在使用其構建器構建查詢時將參數設置爲初始參數。

儘管我可以看到文檔沒有明確地說出關於多線程的任何內容,但這看起來很清楚,它是處理的。這是使用相同的Query對象討論多個線程,因此顯然多個線程可以訪問同一個數據庫。當然,數據庫和DAO處理併發訪問是很正常的,在這種情況下,有很多用於處理高速緩存的經過驗證的技術。

0

默認情況下,GreenDAO緩存並返回高速緩存的實體實例以提高性能。爲了防止這種行爲,你需要調用:

daoSession.clear()

清除所有高速緩存的實例。另外,您可以撥打:

objectDao.detachAll()

清除緩存的情況下,僅針對特定的DAO對象。

您每次需要清除緩存實例時都需要調用這些方法,因此如果要禁用所有緩存,我建議在您的Session或DAO訪問器方法中調用它們。