刷新bean缓存

时间:2014-08-04 15:07:27

标签: java caching weblogic-10.x ejb-2.x

我正在使用一个使用EJB 2的系统。该系统由两个独立的应用程序组成,一个用于用户管理,另一个是包含业务逻辑的实际应用程序。

在业务逻辑应用程序中,我有一个代表用户的bean管理实体bean。 应用程序从用户管理数据库中读取信息,但不能修改它。

每当在用户管理应用程序中修改用户时,都会通知业务逻辑应用程序用户已更改。这是作为对业务应用程序的调用实现的,以删除bean,这会导致Weblogic将其从缓存中删除并删除"删除"它(什么都不做 - 请参阅下面的ejbRemove代码)。下次业务应用程序需要用户时,它将从数据库重新加载它。

我们使用以下代码使单个用户无效:

    try
    {
        UserHome home = (UserAuthHome) getHome("User", UserHome.class);

        User ua = home.findByPrimaryKey(user);
        ua.remove();  // This will remove a single cached User bean in the business logic application
    }
    catch ...

这种方法很好,但有时候(特别是开发时)我需要在业务应用程序中使所有缓存的用户bean 无效。我想以编程方式执行此操作 - 启动管理控制台需要太长时间。有太多用户为每个用户拨打电话。

可能的解决方案可能包括:

- 访问bean缓存并获取缓存的用户bean列表。

- 告诉WLS废弃当前用户bean缓存中的所有项目,并从数据库中重新读取它们。

不幸的是,我不知道如何做其中任何一项。 我试图寻找解决方案,但我的互联网搜索业力并没有找到任何有用的东西。

其他信息:

持久性:

  <persistence-type>Bean</persistence-type>
  <reentrant>false</reentrant>

缓存:

<entity-descriptor>
  <entity-cache>
    <max-beans-in-cache>500</max-beans-in-cache>
    <concurrency-strategy>Exclusive</concurrency-strategy>
    <cache-between-transactions>true</cache-between-transactions>
  </entity-cache>
  <persistence></persistence>
</entity-descriptor>

Bean代码(在业务应用程序中):

public void ejbLoad()
{
    thisLogger().entering(getUser(m_ctx), "ejbLoad()");

    // Here comes some code that connects to the user database and fetches the bean data.
    ...
}

public void ejbRemove()
{
    // This method does nothing
}

public void ejbStore()
{
    // This method does nothing
}

public void ejbPostCreate()
{
    // This method is empty
}

/**
 * Required by EJB spec.
 * <p>
 * This method always throws CreateException since this entity is read only.
 * The remote reference should be obtained by calling ejbFindByPrimaryKey().
 *
 * @return
 * @exception CreateException
 * Always thrown
 */
public String ejbCreate()
    throws CreateException
{
    throw new CreateException("This entity should be called via ejbFindByPrimaryKey()");
}

1 个答案:

答案 0 :(得分:0)

我做了更多的研究,并找到了解决问题的方法。

我能够使用weblogic.ejb.CachingHome.invalidateAll()。但是,为此,我不得不将bean的并发策略更改为ReadOnly。显然,Exclusive并发不会使home接口实现weblogic.ejb.CachingHome

<entity-descriptor>
  <entity-cache>
    <max-beans-in-cache>500</max-beans-in-cache>
    <read-timeout-seconds>0</read-timeout-seconds>
    <concurrency-strategy>ReadOnly</concurrency-strategy>
    <cache-between-transactions>true</cache-between-transactions>
  </entity-cache>
  <persistence></persistence>
</entity-descriptor>

最后,我的新函数invalidateAllUsers的代码:

public void invalidateAllUsers() {
    logger.entering(getUser(ctx), "invalidateAll()"); // getUser returns a string with the current user ( context.getCallerPrincipal().getName() ).

    try {
        UserHome home = (UserAuthHome) getHome("User", UserHome.class); // Looks up the home interface
        CachingHome cache = (CachingHome)home;  // Sweet weblogic magic!
        cache.invalidateAll();
    } catch (RemoteException e) {
        logger.severe(getUser(ctx), "invalidate(date)", "got RemoteException", e);
        throw new EJBException(e);
    }
}