2011-05-01 32 views
6

我要實現的,用戶希望保持自己的搜索結果不變即使他們這樣做,影響由返回的行相匹配的標準動作在Java CRUD應用程序的要求。飼養搜索結果在多個交易一致

困惑?好。讓我給你一個熟悉的例子。在Gmail中,如果您對未讀電子郵件進行高級搜索,則會顯示匹配結果列表。點擊一個條目,然後返回到搜索列表。會發生什麼情況是您剛剛閱讀了該條目,但它並未從原始結果集中消失。只有該行從粗體更改爲正常。

我需要執行完全相同的行爲,但應用程序的設計是這樣一種方式,任何事務第一次堅持,然後UI重新查詢數據庫保持同步。應用程序的複雜性和數據庫的大小使我無法在匹配行中進行簡單的內存緩存並在db和內存中進行更改。

我想通過在Oracle數據庫中創建一箇中間表保存指針匹配記錄和重新查詢只有那些記錄保持UI同步與數據解決在數據庫級別上的問題。有任何想法嗎?

回答

4

在Oracle中,如果你打開一個遊標,該遊標的結果是靜態的,如果不考慮其他事務插入會出現在你的光標一排,或更新或刪除,它在你的光標存在的行。然後

所面臨的挑戰是,如果你想要的結果打開遊標時,從一致不關閉遊標。

+0

但是你只能從遊標讀取一次......如果用戶打算返回到搜索頁面幾次你需要打開多個遊標。 – 2011-05-02 09:34:38

2

您可以使用閃回查詢從過去讀取數據。例如,select * from employee as of timestamp to_timestap('01-MAY-2011 070000', 'DD-MON-YYYY HH24MISS');

僅Oracle存儲用於在有限的時間期間該歷史信息。您需要查看您的保留設置; UNDO_RETENTION參數,UNDO表空間保留大小和適當的大小,以及LOB都有其自己的保留設置。

2

創建到數據庫的兩個連接。

設置第一個只讀(使用SET TRANSACTION READ ONLY)從該連接做你的搜索,但要確保你從未結束,通過發出提交或回滾事務。

由於只讀事務只能看到事務開始時的數據,因此第一個連接永遠不會看到數據庫發生任何更改 - 甚至不會發生任何更改。

然後,您可以在第二次連接中執行更新,而不會影響第一次連接的結果。

如果您不能使用兩個連接,則可以通過使用自治事務的存儲過程來實現更新,然後您可以在只有一個連接的情況下保持只讀事務處於打開狀態。

3

如果UI在數據庫上維護單個會話,則一種解決方案是使用Oracle中的全局臨時表。當您執行搜索時,將唯一ID插入GTT,然後UI僅查詢GTT。

如果UI沒有保持會話打開,你可以做同樣的事情,但用普通的表。然後,當然,您只需添加一些清理代碼即可從表中刪除舊的搜索結果。

+0

這是一個聰明的主意,但需要一些調整來適應賬單。數據訪問通過連接池進行,因此GTT不適用。此外,建議的解決方案需要對數據訪問層進行大量更改,從而導致不必要的副作用和性能問題。我想我需要使用觸發器/存儲過程魔術的組合來創建一個自填充的臨時表,以便儘可能地避免代碼中的數據保留複雜性。 – 2011-05-06 16:33:47