javaee / ejb-spec

See javax.ejb project for API. Contains legacy issues only.
https://github.com/javaee/javax.ejb
6 stars 1 forks source link

Provide @Idempotent functionallity to the EJB Container #100

Open glassfishrobot opened 11 years ago

glassfishrobot commented 11 years ago

My proposal is to add functionality in the EJB-Container to support @Idempotent for Stateless EJB methods.

A method is idempotent, when a call to this method does not have any side-effects. This means, that multiple calls to such a method always give the same result.

So a container could provide this functionality for methods of a Stateless Session Bean, marked with @Idempotent to cache the result of the method for further calls.

An example:

@Stateless
public class MyService {

    @Idempotent
    public Long add(Long a1, Long a2) {
        return a1 + a2;
    }
}

With this, a container is told to handle each call with the same arguments idempotent and return exactly the same value. So a call:

@Stateless
public class AnotherService {

    @EJB
    MyService myService;

    public void someMethod() {
        // assuming, this is the first call ever to this service's method...
        // the container calls the method directly and caches the result.
        System.out.println(myService.add(1024, 42));

        // the container will return always the same value, read from a cache, without explicitly call the method.
        for(int i = 0; i<10; i++) {
            System.out.println(myService.add(1024, 42));
        }
    }
}

A container is responsible for caching the result of the method as well as how long or under which circumstances the result is cached (e.g. WeakReference).

Another responsibility for the container is the error handling and transaction rollback for idempotent methods, especially in cluster environments. (see the similar functionality with weblogic.javaee.Idempotent, but my proposal goes a bit further).

This would be a performance gain, but also a potential risk for developers, that do not know, what they exactly do.

I think, there is a general need for this functionality, even in REST-Resources or in Cluster-Environment to simplify things and to standardize the behavior of containers in this way.

Comments are requested

Affected Versions

[3.2]

glassfishrobot commented 11 years ago

Reported by rherschke

glassfishrobot commented 11 years ago

@arjantijms said: I like the proposal, but want to add that the JCache annotations with respect to the caching aspect do something similar. See e.g. javax.cache: The new Java Caching Standard

Most JCache annotation examples work with the concept of a getter and setter method though (I don't know if tt>@CacheResult</tt and tt>@CachePut</tt can be applied to the same method), but it would probably be useful to coordinate with JCache for this aspect.

glassfishrobot commented 11 years ago

rherschke said: Hi Arjan,

yes, I appreciate to see JSR-107 in next Java EE spec.

Although you could build an tt>@Idempotent</tt method with javax.cache Annotations (or (I already do this) by an proprietary interceptor), there is one little exception:

If the container should handle the "tracking of idempotent method results", he could even decide if - or if not - it has to construct the bean instance itself.

Look at the second example above. The container already injects just a proxy at @EJB MyService myService. The bean at this state in some container implementations isn't instantiated itself nor is it caught from the bean instance pool. The method myService.add() is proxied with the logic to decide whether to return the cached value or to get an instance from the pool (or instantiate one) and invoke the method.

The javax.cache Annotations acts like an interceptor with an "AroundInvoke" method, that does the caching logic. But to have the interceptor's "AroundInvoke" executed, the bean (which is returned from InvocationContext#getTarget()) is completely instantiated before the execution. This isn't necessary in the case, the container is responsible.

Next, the tt>@Idempotent</tt handling by the container is not only responsible for caching the result but also for doing a retry of a method in a cluster environment on another cluster-node instance for example in case the current cluster-node result in an error (which is not an tt>@ApplicationException</tt). This is true, because of the convention behind tt>@Idempotent</tt which means, ALL invocations of this method - even on another cluster-node instance WILL return the SAME value under the same invocation conditions (parameter values...).

So JCache is really fine, but I compare it a bit with tt>@Asynchronous</tt, that is completely the responsibility of the container too.

Many thanks for your comment and for your vote

glassfishrobot commented 11 years ago

Was assigned to mvatkina

glassfishrobot commented 7 years ago

This issue was imported from java.net JIRA EJB_SPEC-100