缓存远程EJB 3.0引用 [英] Caching remote EJB 3.0 reference

查看:113
本文介绍了缓存远程EJB 3.0引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在想如何通过jndi节省查找远程ejb参考的时间。我有一个应用程序需要非常快速地工作,但它也必须调用远程ejb,这会减慢它。

I was thinking how could i save time on looking up remote ejb reference through jndi. I had an application that needed to work very fast, but it also had to call remote ejb which slowed it down.

所以我的解决方案是这样的:
我使用了apache commons-pool库并将其StackObjectPool实现用于我的远程ejb引用缓存。

So my solution was something like this: I took apache commons-pool library and used its StackObjectPool implementation for my remote ejb references cache.

private static final ObjectPool pool = new StackObjectPool(new RemoteEjbFactory());

工厂看起来像这样:

public static class RemoteEjbFactory extends BasePoolableObjectFactory {

    @Override
    public Object makeObject() {
        try {
            return ServiceLocator.lookup(jndi);
        } catch (NamingException e) {
            throw new ConfigurationException("Could not find remote ejb by given name", e);
        }
    }
}

然后我通过借用来获取对象它来自池(如果池中没有自由对象,它使用工厂创建一个):

Then i take object by borrowing it from pool (if no free object in pool it uses factory to create one):

SomeEjbRemote someEjb = null;
try {
        someEjb = (SomeEjbRemoteImpl) pool.borrowObject();
        someEjb.invokeRemoteMethod();
} catch (Throwable t) {
        if (someEjb != null) {
            pool.invalidateObject(someEjb);
        }
        pool.clear(); // Maybe its not neccessary
        someEjb = (SomeEjbRemoteImpl) pool.borrowObject();
        someEjb.invokeRemoteMethod(); // this time it should work
}

当然还有ejb回到游泳池之后成功的invokacion

And of course returning ejb back to pool after successful invokacion

finally {
    try {
         pool.returnObject(someEjb);
    } catch (Exception e) {
        logger.error("Could not return object to pool.", e);
    }
}

据我所知,无法保证远程参考将会保持连接所以如果我们使用缓存的远程ejb捕获异常,我们只是使该对象无效并重试。

As i understand there is no guarantee that remote reference will stay connected so if we catch exception using cached remote ejb, we just invalidate that object and retry.

您如何看待这种方法?这是对的吗?也许其他一些解决方案,建议?

What do you think about such approach? Is it correct? Maybe some other solutions, advices?

推荐答案

来自规范


3.4.9 并发访问会话Bean参考

允许
获取会话bean reference和
尝试从多个
线程同时调用相同的引用
对象。但是,每个线程上生成的客户端
行为取决于

目标bean的并发语义。有关会话bean的并发行为的
的详细信息,请参见第4.3.14节和第4.8.5节。

It is permissable to acquire a session bean reference and attempt to invoke the same reference object concurrently from multiple threads. However, the resulting client behavior on each thread depends on the concurrency semantics of the target bean. See Section 4.3.14 and Section 4.8.5 for details of the concurrency behavior for session beans.

§4.3.14的摘要:

Summary of § 4.3.14:

如果豆是 SLSB ,每次调用都将由应用程序中的一个EJB提供。服务器池。该应用程序。服务器同步调用EJB实例,因此永远不会同时访问每个EJB实例。

If the bean is SLSB, each call will be served by one EJB in the app. server pool. The app. server synchronizes the calls the EJB instances, so each EJB instance are never accessed concurrently.

对于 SFSB ,每次调用都调度到一个特定的EJB实例和应用程序。服务器不同步呼叫。因此,对远程引用的两个并发调用可能会导致对EJB实例的并发访问,然后引发 javax.ejb.ConcurrentAccessException 。客户端负责正确同步对远程引用的访问。

For SFSB, each call is dispatch to one specific EJB instance, and the app. server does not synchronises the call. So two concurrent calls to the remote reference might lead to a concurrent access to the EJB instance which raises then a javax.ejb.ConcurrentAccessException. The client is responsible of the correct synchronization of the access to the remote reference.

§4.8.5是关于EJB单例的,可能不是你正在使用的。

And § 4.8.5 is about EJB singleton, probably not what you are using.

我假设你使用SLSB,因此您不需要在客户端使用池:查找远程bean一次,并使用来自多个线程的相同引用。

I assume you use SLSB, so you don't need to have a pool on the client-side: look up the remote bean once, and use the same reference from multiple threads.

然而,您可以执行基准来查看使用多个引用是否可以提高性能,但增益 - 如果有的话 - 可能是可忽略的比较到远程调用本身的成本。

You could however do a benchmark to see if using multiple reference improves performance, but the gain -- if any -- is probably neglectable compare to the cost of the remote invocation itself.

如果那时你仍然决定有多个远程引用,我会建议另一种设计。基于您的问题,我假设您有一个多线程应用程序。您可能已经为线程使用池,因此参考池可能是多余的。如果每个线程在创建时获得远程引用,并且线程被池化,则不会有那么多远程查找并且简化了设计。

If then you still decide to have more than one remote reference, I would suggest an other design. Based on your question I assume you have a multi-threaded app. You probable already use a pool for the threads, so a pool for the reference is maybe redundant. If each thread gets a remote reference when it is created, and threads are pooled, there won't be that many remote lookup and the design is simplified.

我的2美分

这篇关于缓存远程EJB 3.0引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆