jsr342-experts@javaee-spec.java.net

[jsr342-experts] EJBs and JTA transactional interceptors

From: Bill Shannon <bill.shannon_at_oracle.com>
Date: Mon, 30 Jan 2012 12:40:16 -0800

We've been trying to figure out how the new JTA transactional interceptor
support should interact with EJBs. Here's some options we've considered:

1. The new transaction annotations are not allowed to be used on EJBs.
    This error would be detected at deployment time.

2. The new transaction annotations have no effect when used on EJBs.
    This would likely be very surprising to users.

3. The EJB container does not understand the new transaction annotations
    at all and behaves the same with regard to the exceptions that are thrown
    as it would if the application were to throw the same exceptions in
    an EJB that was not annotated with the new transaction annotations.
    The exceptions the EJB container sees at point B above are handled
    the same as they would be if CDI were removed from the picture.
    The EJB container does exception wrapping and transaction rollback
    based only on its existing rules, including use of the existing
    EJB @ApplicationException annotation. At point A the application
    sees exceptions that might be wrapped in the normal EJB way.

    Note that the EJB container will be performing its normal CMT
    behavior, including the default transaction attribute of REQUIRES
    and the normal EJB exception wrapping behavior. If the EJB Bean
    wants to use the new JTA transaction annotations it will likely want
    to disable the EJB CMT support by specifying an EJB transaction
    attribute of SUPPORTS (which means the EJB container will never
    start a transaction itself and will pass through any existing
    transaction context).

4. Like #3, but the EJB container understands both the existing
    EJB @ApplicationException annotation as well as any new such
    annotation defined by JTA. This changes which exceptions will
    be wrapped before returning to the application, and what will
    happen to any transaction that the EJB container might have started.

    And like #3, the application will likely want to disable EJB CMT
    by specifying an EJB transaction attribute of SUPPORTS.

5. Like #4, but the EJB container also detects the use of the new
    JTA transaction annotations and changes the default CMT behavior
    to SUPPORTS.

    And like #4, the EJB container still does its normal exception wrapping.

6. Like #5, but the EJB container also changes the exception wrapping
    rules to match those of a standalone CDI bean using the new JTA
    transaction annotations (i.e., no exception wrapping at all).



In cases #5 and #6, it's TBD what should happen if the bean uses both
the EJB transaction annotations and the JTA transaction annotations.
Given a possible implementation (see appendix), you can predict the
effect, but it's almost certainly not what the user wants, and so
likely should be treated as an error, probably detected at deployment
time.

The current EJB exception wrapping behavior is somewhat arcane. You
could imagine a new EJB annotation @DontWrapExceptions that would
disable this behavior. This could be used explicitly in cases
#3 - #5 (it's implicit in case #6), or in other existing uses of EJB.

Note that remote EJBs would need to continue to follow the existing
rules for remote exceptions.

Which option above do you prefer?





--- Appendix (read only if you're confused)

For the options #3 - #6, it's helpful to think about how
this might be implemented. For example, consider an
implementation where the EJB container asks CDI to instantiate
the class that is the EJB bean. CDI performs injection on
the bean and returns a wrapper or subclass of the bean that
handles any interceptors declared for the bean. The EJB
container then invokes methods on the bean using this object
reference returned by CDI. The EJB container does no
interceptor handling of its own. This may or may not be a
reasonable or correct implementation approach, but for the
purposes of the following, let's consider it. Here's a picture:

app reference ----> EJB container ----> CDI ----> EJB bean
                A B