2012-03-21 60 views
3

我想要一個支持事務的簡單緩存。簡單地說,我的意思是我只想在啓動時加載所有數據,不需要驅逐等。 (簡單的地圖可以)。用交易的Java緩存

但是,它應該支持事務,因爲如果數據庫更改失敗,對緩存所做的更改也會回滾。

我聽說過JTA,但它似乎太多了我需要的東西。如果在數據庫事務中拋出SQLException,手動回滾緩存將會很好。

有沒有任何選擇?

如果沒有人能指點我一個關於JTA的好教程?例如。示例以及所需的包/類。注意:我創建了一個框架,因此它必須能夠在沒有應用程序容器的情況下獨立運行。

編輯:

忘記了1個非常重要的問題:

緩存的對象是不可改變的!更新意味着用一個等於舊的對象(基於ID的等於方法)的新對象替換它。

編輯2:

寫JPA代替JTA ...

編輯3:

解釋爲什麼簡單的地圖不工作:

我有兩個實體類型。我會稱它們爲複合和元素。化合物可以由多種元素組成,每種元素可以出現在多種化合物中。 元素由我的框架管理。例如,只能直接添加化合物。用戶通過指定其元素來添加新化合物。然後框架選擇並退出元素並將其與新化合物相關聯或創建一個新元素。

我正在緩存所有元素,其中每個元素包含元素出現的化合物ID的集合。原因在於框架做了一種特殊的搜索(例如子圖同構)。對於每個這樣的搜索,整個!!!數據集(所有元素)需要從數據庫加載,因此需要緩存。

因此,如果添加或更新了新化合物,則高速緩存中受影響的元素也必須更新。

解決方案:

做了什麼,我在評論中說: - 保持IDS內存中的所有更改的對象(=整數),然後只在數據庫事務提交之後更新變化的。

private void updateSearchCache(Collection<String> changedIds, 
     Connection connection) { 

    synchronized (searchCache) { 
     for (String id : changedIds) { 
      Object myObject = getSearchObject(id, connection); 
      searchCache.put(id, myObject); 
     } 
    } 
} 

回答

2

難道你只是把你的數據寫入Map之後事務被提交到數據庫,你能嗎?

因此,您的Map將只包含已經在數據庫中的數據。

+0

一般來說是真的,但對我而言不起作用。事情是我正在處理非常重的對象,應用程序必須能夠從一個文件中一次性添加許多這樣的對象。所以我從文件(線程1)讀取並同時使用BlockignQueue插入(線程2)來限制內存中對象的數量。因此,一旦事務提交,我不知道要插入緩存。還有更多,這也阻礙了這種方法。 – 2012-03-21 16:05:27

+0

@beginner_您可以保存提交給數據庫的對象的ID嗎?如果是,則可以在處理整個文件之後,但在開始計算之前從數據庫中讀取它們。當然,只有在承諾對象的總大小可以放入應用程序的堆中時,這纔會起作用。 – 2012-03-21 16:10:44

+0

如果不是,則只能將緩存中最後N個最近訪問過的項目保存在緩存中。 – 2012-03-21 16:11:51

0

Berkeley DB可以用來創建in-memory tables並且具有transactional support

這是一個很好的選擇,如果你想存儲的是blob-> blob映射,但它不是一個對象緩存。

+0

它與HSQLDB內存表相比如何?但我認爲我們都認爲這比簡單的Map訪問慢很多。閱讀必須非常快! – 2012-03-21 17:51:50

0

事務性緩存可能與infinispan。雖然它被設計爲一個羣集緩存,但它可以是easily run on one machine。 cache-api擴展了java.util.Map,易於使用。

+0

剛纔看到我在我的問題中寫了JPA而不是JTA。最好我想避免它,因爲JPA似乎對我的用例相當沉重,但也許我錯了。 – 2012-03-21 16:24:45