2 Replies Latest reply on Dec 1, 2005 7:54 PM by gavin.king

    @SerializedConcurrentAccess, @Reentrant needed?

    starksm64

      Based on a JBossSeam usecase discussion where two SFSBs were involved in a converstation that was re-entrant, but did not involve concurrent access, a "no concurrent calls to an SFSB" exception was seen. Historically I don't think we have made a distinction between the two uses in terms of throwing an exception. A workaround is to use the proprietary @SerializedConcurrentAccess, but this does not seem to be exactly the correct semantic, and brings up the question of whether reentrancy is really disallowed. From the current ejb spec:

      "ejb-3_0-pr-spec-ejbcore.pdf" wrote:

      4.3.12 Serializing Session Bean Methods
      The container serializes calls to each session bean instance. Most containers will support many instances of a session bean executing concurrently; however, each instance sees only a serialized sequence of method calls. Therefore, a session bean does not have to be coded as reentrant.

      The container must serialize all the container-invoked callbacks (that is, the lifecycle and timeout callback methods, beforeCompletion, and so on), and it must serialize these callbacks with the client-invoked business method calls.

      Clients are not allowed to make concurrent calls to a stateful session object. If a client-invoked business method is in progress on an instance when another client-invoked call, from the same or different client, arrives at the same instance of a stateful session bean class, if the second client is a client of the bean?s business interface, the concurrent invocation may result in the second client receiving the javax.ejb.EJBException.


      and

      "ejb-3_0-pr-spec-ejbcore.pdf" wrote:

      4.4.4 Restrictions for Transactions
      The state diagram implies the following restrictions on transaction scoping of the client invoked business methods. The restrictions are enforced by the container and must be observed by the client programmer.
      * A session bean instance can participate in at most a single transaction at a time.
      * If a session bean instance is participating in a transaction, it is an error for a client to invoke a method on the session object such that the transaction attribute specified in the bean?s metadata annotations and/or the deployment descriptor would cause the container to execute the method in a different transaction context or in an unspecified transaction context. In such a case, the javax.ejb.EJBException will be thrown to a client of the bean?s business interface. If the EJB 2.1 client view is used, the container throws the java.rmi.RemoteException to the client if the client is a remote client, or the javax.ejb.EJBException if the client is a local client.


      The wording of the concurrent access restrictions is a bit vague in the context of this usecase. When speaking of "client-invoked business method is in progress on an instance when another client-invoked call, from the same or different client", I take this to mean an invocation neccessarily via another thread, not another invocation on the same thread/transaction due to a reentrant call graph. I take this view because there is no use of reentrant in this particular paragraph. There is the earlier statement about "... session bean does not have to be coded as reentrant." that can be viewed as preventing this. There is a difference between a bean that works with one thread vs a bean that works with one thread AND reentrantrancy.

      I think this issue needs to be raised on the ejb eg, but if the strictest interpretation is taken that neither concurrent nor reentrant access is allowed, do we need a different form of access annotation, @Reentrant, or is this really what @SerializedConcurrentAccess equates to? I could imagine that @Reentrant would start a seperate tx for each distinct top-level client request and there after behave as @SerializedConcurrentAccess.


        • 1. Re: @SerializedConcurrentAccess, @Reentrant needed?
          gavin.king

          Actually I think this is the most relevant bit.


          4.7.11 Non-reentrant Instances
          The container must ensure that only one thread can be executing an instance at any time. If a client request arrives for an instance while the instance is executing another request, the container may throw the javax.ejb.EJBException to the second client[18]. If the EJB 2.1 client view is used, the container may throw the java.rmi.RemoteException to the second request if the client is a remote client, or the javax.ejb.EJBException if the client is a local client. [19]

          Note that a session object is intended to support only a single client. Therefore, it would be an application error if two clients attempted to invoke the same session object.

          One implication of this rule is that an application cannot make loopback calls to a session bean instance.


          • 2. Re: @SerializedConcurrentAccess, @Reentrant needed?
            gavin.king

            I just realized that this section of the spec makes the SessionContext.getEJBObject() method utterly useless for anything.

            What a massive flaw in the spec.