users@jta-spec.java.net

[jta-spec users] Re: rough draft of JTA 1.2 section 3.7 Transactional Annotation

From: Ian Robinson <ian_robinson_at_uk.ibm.com>
Date: Mon, 25 Feb 2013 22:35:27 +0000

Linda, thanks for the response.
On your final comment


"With regard to mixing @Transactional with UserTransaction -- while the
application may get messed up, we believe the behaviors are well-defined."

Paul has subsequently clarified that
"I've added the following in 3.1:
" If an attempt to use the UserTransaction is made from within a bean or
method annotated with @Transactional an IllegalStateException must be
thrown."
"

which clears up the concern I had about that.


This just leaves my concern about mixing @Transactional and EJB CMT beans.
Your responses below clarify how an implementation is expected to work in
this case but I'd like a little more time to discuss this with the IBM
team.

I still fear it may be confusing that, for example, a non-transactional
client calling a CMT bean annotated with
@Transactional(NEVER|SUPPORTS|NOT_SUPPORTED) and with no CMT annotation
gets a javax.ejb.TransactionRolledbackLocalException (on account of the
implicit @TransactionAttribute(Required) for CMT). I am not, by the way,
suggesting that the CMT default transaction policy should be influenced by
any CDI TxType. Just observing that its a little....awkward.

Regards,
Ian




From: Linda DeMichiel <linda.demichiel_at_oracle.com>
To: Ian Robinson/UK/IBM_at_IBMGB,
Cc: users_at_jta-spec.java.net, Marina Vatkina
<marina.vatkina_at_oracle.com>, Paul Parkinson <paul.parkinson_at_oracle.com>,
Pete Muir <pmuir_at_redhat.com>, Bill Shannon <bill.shannon_at_oracle.com>
Date: 15/02/2013 22:42
Subject: [jta-spec users] Re: rough draft of JTA 1.2 section 3.7
Transactional Annotation



Ian,

Our apologies for being so late in getting a response to you on this.

Please see further below for the individual items.....


On 1/18/2013 6:00 AM, Ian Robinson wrote:
> Paul, Bill and all,
> I apologise for my slow response.
>
> Let me start by saying that I think the @Transactional proposal for JTA
is a good thing. Just not the way it is
> suggested to be combined with EJB CMT.
>
> In the draft proposal at
http://java.net/projects/jta-spec/sources/spec-source-repository/show
> the new annotations are not actually defined. So, for example. where the
text now says:
> "If a managed been annotated with a TxType of NEVER is called from
within a transaction context, an
> InvalidTransactionException is thrown."
> For example, there is no definition (or mention elsewhere) of TxType.
>

This is now covered in the JTA docs.

>
> I continue to believe we're making life too hard for container providers
for a use case that is a "best practice to
> avoid" and I think we could spend a lot of time arguing over the
behavioural details of edge cases that would only be
> driven by a really peculiar application.
>
> The current proposed wording in the draft is:
>
> "When Transactional annotated managed beans are used in conjunction with
EJB container managed
> transactions the EJB container behavior is applied before the bean is
called. When the bean is called
> the CDI behavior is applied before calling the bean's methods. It is
best practice to avoid such use of
> Transactional annotations in conjunction with EJB container managed
transactions in order to avoid
> possible confusion."
>
> I agree we don't want to complicate the deployment process by requiring
it to detect and prevent the combination of CMT
> and @Transactional annotations. But I also don't want to complicate our
implementation or end up with an implementation
> that is in conflict with any compliance tests. So part of this
discussion needs to be over the definition of the
> specific compliance tests and allowed outcomes and which spec (JTA, EJB
or CDI) they'll be part of. By the way, I'd
> really like to see a JTA TCK for JTA compliance rather than it being all
entangled in the Java CTS.
>
> In the spirit of not /requiring /the deployment process to detect and
prevent, could I suggest something like:
>
> "When Transactional annotated managed beans are used in conjunction with
EJB container managed transactions the EJB
> container behavior is unspecified and not portable.Valid container
implementations include, but are not limited to:
>
> * the bean may fail to deploy
> * the Transactional annotation may be ignored
> * the EJB container behavior is applied before the bean is called.
When the bean is called the CDI behavior is
> applied before calling the bean's methods.
>
> It is best practice to avoid such use of Transactional annotations in
conjunction with EJB container managed
> transactions in order to avoid possible confusion. and lack of
portability."
>

We believe that the interaction of EJB CMT and the new transactional
interceptors is well defined, and that therefore only the third of
these options should be applicable. However, a container might
produce warnings at deployment time, if it detects the use of both EJB
CMT and transactional interceptors on the same bean.

>
> Let me continue the discussion over why I don't like the option to
require support of both annotations on the same bean.
>
> I enumerated some of the confusing scenarios below although I imagine
there are plenty more. Going through just these:
> *e.g. #1 : @TransactionAttribute(MANDATORY) + @Transactional(NEVER)***
>
> I believe the end result MUST BE:
> Throw javax.transaction.TransactionRolledbackException to remote client;
throw
> javax.ejb.TransactionRolledbackLocalException to local client.
>

Yes. Under the proposed behavior that the transactional interceptor
throw the new TransactionalException runtime exception that wraps the
InvalidTransactionException, the EJB container would mark for rollback
the transaction and throw one of the RolledbackExceptions to the client.



> Anything else would require a change to the EJB spec.
> Paul said:
> "I may send a separate dedicated email on this topic but we do need to
also decide what exception is to be thrown when a
> bean with TxType Never is called from within a transactional context as
currently it throws an EJBException. Eg, should
> we throw InvalidTransactionException?"
>
> My comment to this is that I think your current implementation is
correct and consistent with the EJB spec. But as you
> say, its awkward given the new proposed JTA text:
> "If a managed been annotated with a TxType of NEVER is called from
within a transaction context, an
> InvalidTransactionException is thrown."
>

Yes, now a TransactionalException wrapping the
InvalidTransactionException.

>
> *e.g. #1a : @Transactional(NEVER)**on a CMT EJB with no
TransactionAttribute*
>
> This is even more confusing since default EJB CMT is REQUIRED and the
result therefore needs to be the same as the first
> case above.
>

In this case, the EJBException would be thrown to the EJB's client if
the transaction has been started on behalf of the EJB.

>
> *e.g. #2 Exception handling*
>
> For an ISE how would I reconcile:
>
> @TransactionAttribute(REQUIRES_NEW) + @Transactional(REQUIRED,
dontRollbackOn={IllegalStateException.class})
> The EJB container is /required/ to rollback the transaction in the case
of an ISE despite the CDI annotation. So the
> outcome must be a rollback on ISE despite the explicit dontRollbackOn
>

Yes. While the transactional interceptor does not mark the
transaction for rollback due to the IllegalStateException, it does
pass the IllegalStateException up the call chain. When it hits the
EJB container handing the CMT, the EJB container is required to
rollback the transaction.

> More evidence for allowing unspecified behaviour.
>
> *e.g #3.****_at_TransactionAttribute(MANDATORY) +
@Transactional(REQUIRES_NEW)*
>
> In the case of any system exception, the EJB container exception
processing behaviour depends on whether the EJB runs in
> the caller's transaction or not. A MANDATORY EJB is always considered to
be running in the caller's transaction and in
> the case of the bean throwing a system exception (EJB 3.1 Table 15) must
mark the caller's transaction rollback_only and
> throw EJBTransactionRolledbackException. This would also be the case if
you had a distinct client -> EJB (Mandatory) ->
> Bean (RequiresNew)
>
> On the other hand you could interpret this as the case where the bean is
not running in the client's context in which
> case the EJB container should throw EJBException and not mark the
caller's transaction rollback_only. I think this would
> be an incorrect interpretation but given there is only one bean involved
I think it is debatable.
>

We agree that this is incorrect. For example, the transactional
interceptor might mark some exception (say IllegalStateException) as
not causing rollback. In this case, the RequiresNew transaction would
commit, but the transaction corresponding to Mandatory should be
marked for rollback.


> *e.g #4 Client has no context. EJB
specifies:****_at_TransactionAttribute(REQUIRES) +
@Transactional(REQUIRES_NEW)***
> I'd expect some implementations may start a single transaction and some
do a start, suspend, start second.
> This isn't an issue so long as neither approach is prevented.
>

Again, this must be implemented as two transactions, for the same
reasons as above in #3.

> *Also - not related to EJB: Mixing @Transactional with direct access to
UserTransaction*
> Just as the EJB spec prevents access to UserTransaction inside a CMT
bean, we need either the JTA spec to prevent access
> to UserTrasnaction within a managed bean that uses @Transactional
otherwise the interceptor cannot efficiently provide
> transactional integrity. whose snaction
>

With regard to mixing @Transactional with UserTransaction -- while the
application may get messed up, we believe the behaviors are well-defined.

>
> *Finally*, there's a typo in 3.7:
> Conversely, the dontRollbackOn element can be set to indicate which
exceptions should do notcause
> the interceptor to mark the transaction for rollback.
>

Thank you again for your feedback and patience.

Regards,

-Linda


> Regards,
> Ian
> /
> /
>
>
>
> From: Bill Shannon <bill.shannon_at_oracle.com>
> To: Paul Parkinson <paul.parkinson_at_oracle.com>,
> Cc: users_at_jta-spec.java.net, Pete Muir <pmuir_at_redhat.com>, Linda
DeMichiel <linda.demichiel_at_oracle.com>, Marina Vatkina
> <marina.vatkina_at_oracle.com>
> Date: 14/01/2013 22:34
> Subject: [jta-spec users] Re: rough draft of JTA 1.2 section 3.7
Transactional Annotation
>
------------------------------------------------------------------------------------------------------------------------
>
>
>
> (Someone may need to forward this to Ian and/or users_at_jta-spec.)
>
> We tried to define the behavior so that an EJB that *is* a CDI bean that
happens to use the new transactional
> interceptors behaves the same as an EJB that *calls *a CDI bean that
happens to use the new transactional interceptors.
> All the cases should be well-defined, but that doesn't mean they aren't
confusing.
>
> Checking for these unexpected and potentially confusing cases seems like
a good job for a tool like FindBugs. We
> preferred not to complicate the deployment process by requiring it to
detect these cases and force deployment to fail,
> even though the behavior of these cases is fully defined.
>
> Paul Parkinson wrote on 12/26/12 15:45:
> Hi Ian,
>
> Definitely good point(s) and there were lengthy discussions on this when
first drafting the feature though I'm afraid
> they were just between Oracle and JBoss/CDI at the time.
>
> Those parties are cc'd and can correct me if I've forgotten or missed
anything but the main rationale stemmed from the
> fact that we are trying to decouple the specs as much as possible in
general and as EJB CMT is a special case here the
> interaction of transactional interceptors with CMT should be mentioned
in the EJB spec.
>
> I may send a separate dedicated email on this topic but we do need to
also decide what exception is to be thrown when a
> bean with TxType Never is called from within a transactional context as
currently it throws an EJBException. Eg, should
> we throw InvalidTransactionException?
>
> Thanks,
> Paul
>
> On Dec 10, 2012, at 4:30 AM, Ian Robinson wrote:
>
> I probably haven't thought about this enough yet but....
> "It is best practice to avoid such use of Transactional annotations in
conjunction with EJB container managed
> transactions in order to avoid possible confusion."
>
> Why wouldn't we just want to make ANY such combination illegal? There
are some odd combinations and difficult to explain
> behaviours otherwise
>
> e.g. #1 : @TransactionAttribute(MANDATORY) + @Transactional(NEVER)
>
> e.g. #2 Exception handling - how would I reconcile:
>
> @TransactionAttribute(REQUIRES_NEW) + @Transactional(REQUIRED,
dontRollbackOn={IllegalStateException.class})
> In the case of an ISE, the CMT is required to be rolledback but the CDI
annotation is in conflict.
>
> e.g #3.
>
> @TransactionAttribute(REQUIRES) + @Transactional(REQUIRES_NEW)
> Assume the EJB throws an ISE.
> According to Table 19 in the EJB spec, "Bean method runs in the context
of the caller?s transaction. This case may
> happen with Required, Mandatory, and Supports attributes."
> But it is now no longer true that an EJB with
@TransactionAttribute(REQUIRES) always "runs in the context of the
> caller?s transaction". In the case of an ISE does the caller receive
javax.ejb.EJBTransactionRolledbackException or
> EJBException?
>
> e.g #4.
> Client has no context. EJB specifies:
> @TransactionAttribute(REQUIRES) + @Transactional(REQUIRES_NEW)
> The text leads me to believe I'd start 2 transactions here. Is that
right?
> So what about just:
> @Transactional(REQUIRES_NEW) on a CMT EJB?
> Doesn't that have to be the same as the former case since
@TransactionAttribute(REQUIRES) is the default for CMT?
>
> My head aches....
>
> Regards,
> Ian/
> /
>
>
>
> From: Paul Parkinson <_paul.parkinson_at_oracle.com_ <
mailto:paul.parkinson_at_oracle.com>>
> To: _users_at_jta-spec.java.net_ <mailto:users_at_jta-spec.java.net>,
> Date: 06/12/2012 22:24
> Subject: [jta-spec users] rough draft of JTA 1.2 section 3.7
Transactional Annotation
>
------------------------------------------------------------------------------------------------------------------------
>
>
>
> Hi,
>
> Below is a rough first run of the JTA 1.2 section 3.7 Transactional
Annotation, _http://java.net/jira/browse/JTA_SPEC-5_
>
> Thank you for any feedback as we need to close this down in the next
couple weeks.
>
> Regards,
> Paul
>
>
> 3.7 Transactional Annotation
>
> The javax.transaction.Transactional annotation provides the application
the ability to control transaction boundaries on
> CDI managed beans, as well as classes defined as managed beans by the
Java EE
> specification such as servlets, JAX-RS resource classes, and JAX-WS
service endpoints, declaratively. This provides the
> semantics of EJB transaction attributes in CDI without dependencies such
as RMI. This support is implemented via an
> implementation of a CDI interceptor that conducts the necessary
suspending, resuming, etc. [*todo specify the number
> used for the transactional interceptor, so that others can choose to
order their interceptors before or after the
> transactional interceptor; coordinate with CDI for this]
>
> By default checked exceptions do not result in the transactional
interceptor marking the transaction for rollback and
> instances of RuntimeException and its subclasses do. This default
behavior can be overridden by specifying which
> exceptions result in the interceptor marking the transaction for
rollback. The rollbackOn element can be set to indicate
> which exceptions should cause the interceptor to mark the transaction
for rollback. Conversely, the dontRollbackOn
> element can be set to indicate which exceptions should do not cause the
interceptor to mark the transaction for
> rollback. When a class is specified for either of these elements, the
designated behavior applies to subclasses of that
> class as well. If both elements are specified, dontRollbackOn takes
precedence.
>
> The following are some example usages of rollbackOn and dontRollbackOn
elements.
>
> - The following will override behavior for application exceptions,
causing the transaction to be marked for rollback for
> all application exceptions.
> @Transactional(rollbackOn={Exception.class})
>
> - The following will prevent transactions from being marked for rollback
by the interceptor when an
> IllegalStateException or any of its subclasses reaches the interceptor.
> @Transactional(dontRollbackOn={IllegalStateException.class})
>
> - The following will cause the transaction to be marked for rollback for
all runtime exceptions and all SQLException
> types except for SQLWarning.
> @Transactional(
> rollbackOn={SQLException.class},
> dontRollbackOn={SQLWarning.class}
> )
>
> EJB application exceptions (i.e., runtime exceptions annotated with
@ApplicationException) are treated just as any other
> runtime exceptions unless otherwise specified.
>
> When Transactional annotated managed beans are used in conjunction with
EJB container managed transactions the EJB
> container behavior is applied before the bean is called. When the bean
is called the CDI behavior is applied before
> calling the bean's methods. It is best practice to avoid such use of
Transactional annotations in conjunction with EJB
> container managed transactions in order to avoid possible confusion.
>
> ?Java Transaction API Reference? on page 30 has a full description of
this annotation
>
>
> [...]
>
>
> /**
> * Annotation used by applications to control transaction boundaries on
CDI managed beans, as well as
> * classes defined as managed beans by the Java EE specification such as
servlets, JAX-RS resource classes, and JAX-WS
> * service endpoints, declaratively. This provides the semantics of EJB
transaction attributes in CDI without
> * dependencies such as RMI. This support is implemented via an
implementation of a CDI interceptor that conducts the
> * necessary suspending, resuming, etc. [*todo specify the number used
for the transactional interceptor, so that others
> * can choose to order their interceptors before or after the
transactional interceptor; coordinate with CDI for this]
> * [*open issue as to whether the "value" attribute of the
"Transactional" annotation should be binding or not]
> *
> * By default checked exceptions do not result in the transactional
interceptor marking the transaction for rollback
> * and instances of RuntimeException and its subclasses do. This default
behavior can be overridden by specifying
> * which exceptions result in the interceptor marking the transaction for
rollback. The rollbackOn element can be set
> * to indicate which exceptions should cause the interceptor to mark the
transaction for rollback. Conversely, the
> * dontRollbackOn element can be set to indicate which exceptions should
do not cause the interceptor to mark the
> * transaction for rollback. When a class is specified for either of
these elements, the designated behavior applies
> * to subclasses of that class as well. If both elements are specified,
dontRollbackOn takes precedence.
> *
> * EJB application exceptions (i.e., runtime exceptions annotated with
@ApplicationException) are treated just as any
> * other runtime exceptions unless otherwise specified.
> *
> * When Transactional annotated managed beans are used in conjunction
with EJB container managed transactions the EJB
> * container behavior is applied before the bean is called. When the bean
is called the CDI behavior is applied before
> * calling the bean's methods. It is best practice to avoid such use of
Transactional annotations in conjunction with
> * EJB container managed transactions in order to avoid possible
confusion.
> *
> *
> * @since JTA1.2
> */
> @Inherited
> @InterceptorBinding
> @Target({ElementType.TYPE, ElementType.METHOD})
> @Retention(value = RetentionPolicy.RUNTIME)
> public @interface Transactional {
> TxType value() default TxType.REQUIRED;
>
> public enum TxType {REQUIRED, REQUIRES_NEW, MANDATORY, SUPPORTS,
NOT_SUPPORTED, NEVER}
>
> Class[] rollbackOn() default {};
>
> Class[] dontRollbackOn() default {};
>
> }
>
> Unless stated otherwise above:
> IBM United Kingdom Limited - Registered in England and Wales with number
741598.
> Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6
3AU
>
>
>
> Unless stated otherwise above:
> IBM United Kingdom Limited - Registered in England and Wales with number
741598.
> Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6
3AU



Unless stated otherwise above:
IBM United Kingdom Limited - Registered in England and Wales with number
741598.
Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU