java - Wildfly - Infinispan 事务配置

标签 java transactions ejb wildfly infinispan

我正在使用 Wildfly 8.2 及其附带的 Infinispan (6.0.2),并且我尝试将某些 Oracle 数据库表中的所有值缓存在 Infispan 缓存中。在大多数情况下,它似乎有效,但有时却无效。当访问cache.values()时(这对于性能来说也可能不是一个好主意,但只是一个例子)它有时看起来是空的,有时它包含正确的值。因此我认为这可能是交易配置的问题。当使 Infinispan 缓存成为非事务性时,问题就消失了。

访问缓存和数据库的服务是一个具有容器管理事务的 EJB bean。服务初始化时,所有数据都从数据库加载(它不包含很多条目)。 根据what's new in ejb 3.2应该可以在 EJB 中以事务方式访问数据库 Singleton bean 。

数据源和Infinispan缓存的配置是否正确?我可以将非 XA 数据源与 Infinispan 一起使用并期望其一致工作吗?根据Infinispan doc , NON_XA意味着 Infinispan 正在注册为同步,这应该没问题,不是吗?

缓存在standalone-full.xml中配置如下(删除<transaction mode="NON_XA" locking="PESSIMISTIC"/>时,问题消失,但代价是没有事务缓存):

        <cache-container name="cacheContainer" start="EAGER">
            <local-cache name="my_table_cache">
                <locking isolation="REPEATABLE_READ"/>
                <transaction mode="NON_XA" locking="PESSIMISTIC"/>
            </local-cache>
        </cache-container>

Oracle DS 定义如下

           <datasource jndi-name="java:jboss/datasources/myDataSource" pool-name="dataSource" enabled="true">
                <connection-url>jdbc:oracle:thin:@127.0.0.1:1523:orcl</connection-url>
                <driver>ojdbc7.jar</driver>
                <pool>
                    <max-pool-size>25</max-pool-size>
                </pool>
                <security>
                    <user-name>myuser</user-name>
                    <password>myuser</password>
                </security>
                <timeout>
                    <blocking-timeout-millis>5000</blocking-timeout-millis>
                </timeout>
            </datasource>

我的服务(dao 使用简单的 JDBC 操作,而不是 Hibernate 或类似操作)

@Singleton
@ConcurrencyManagement(ConcurrencyManagementType.BEAN)
public class MyService {

@Resource(lookup = "java:jboss/infinispan/container/cacheContainer")
protected EmbeddedCacheManager cm;

protected Cache<String, MyEntity> cache;

@PostConstruct
private void init() {
    try {
        cache = getCache();
    } catch (SQLException ex) {
        log.fatal("could not initialize caches", ex);
        throw new IllegalStateException(ex);
    }
}

public Cache<String, MyEntity> getCache() {
    Cache<String, MyEntity> cache = cm.getCache(getCacheName(), true);
    fillCache(cache);
    return cache;
}

protected void fillCache(Cache<String, MyEntity> cache) {
    List<MyEntity> entities = myDao.getEntities();
    for (MyEntity e : entities) {
        cache.put(e.getKey, e);
    }
}

public MyEntity getEntity(String key) {
    return cache.get(key);
}
public void insert(MyEntity entity) {
    myDao.insert(entity);
    cache.put(entity.getKey(), entity);
}
public void debug() {
    log.debug(cache.values());
}
}

最佳答案

当使用 NON_XA 事务时,未能在缓存中提交 TX 可能会让事务提交,并且您不会收到任何告诉您缓存不一致的异常。

至于 cache.values(),在 Infinispan 7.0 之前,它仅返回本地条目,但是在您的情况下这应该不重要 - 使用本地缓存,所有条目都是本地的。该操作的事务一致性应该保持。我没有发现您的配置有任何问题。

一般来说,我建议在 Hibernate ORM 中使用 Infinispan 模块,而不是尝试自己进行缓存,如此处所示。

关于java - Wildfly - Infinispan 事务配置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30804772/

相关文章:

c# - Java编码base64,C#解码

google-analytics - 将自定义指标添加到谷歌分析交易

java - 使用分布式事务时无法调用commit

ejb - EJB3 和 JNDI 查找中的 SessionContext.getBusinessObject()

unit-testing - 如何测试 EJB 3.0?

jboss - 添加Jboss启动/关闭逻辑

java - 如何用java修改html textview值

java - 实体未找到异常 : Bean has been deleted - lazy loading failed

.net - 在单线程上使用事务时 sqlite 和 SubSonic 的锁定问题

java - 我的输出为 Null,而不是使用字符串的默认值