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:
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.
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.