2012-03-21 56 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