Hi Bill,
I could live with either option #1 or option #3 (#2 and 34 are
non-starters, in my book). I am leaning towards option #1 since it's more
declarative. You know exactly what transactional context will exist just
by looking at the specific @PostConstruct or @PreDestroy method
declarations. You don't have to know and understand the class level
@Transactional value to know how the @PostContstruct or @PreDestroy will
process.
I think if we go with option #3, then the wording for the explanation
needs a little beefing up. For example, the stated example for MANDATORY
is very clear, but I'm fuzzy on what would happen if the value for
@Transactional is either SUPPORTED or REQUIRES. Would both of these also
behave as if REQUIRES_NEW was specified? Or, does some other rule come
into effect? This is why I am leaning towards option #1.
----------------------------------------------------------------------------------------------------------------------------------------------------------------
Kevin Sutter, Java EE and Java Persistence API (JPA) architect
mail: sutter_at_us.ibm.com, Kevin Sutter/Rochester/IBM
http://webspherepersistence.blogspot.com/
phone: tl-553-3620 (office), 507-253-3620 (office)
http://openjpa.apache.org/
From: Bill Shannon <bill.shannon_at_oracle.com>
To: jsr342-experts_at_javaee-spec.java.net,
Date: 03/13/2013 05:30 PM
Subject: [javaee-spec users] [jsr342-experts] Re: transactional
interceptors and lifecycle methods
I really would like to get feedback from more expert group members.
"I don't know" and "I don't care" are acceptable responses.
Bill Shannon wrote on 03/11/13 10:35:
> We recently discovered an issue with the interaction between the
> new @Transactional interceptors and the @PostConstruct method.
> Should @PostContruct (and @PreDestroy) methods be transactional,
> and if so how should the transaction type be controlled?
>
> We'd like your feedback on this issue before Friday, March 15.
>
> We've come up with four options for how this could work:
>
> 1. @PostConstruct is not transactional by default, but @Transactional
> is allowed.
>
> @Transactional(MANDATORY)
> public class MyBean {
> @PostConstruct
> public void postConstruct() {
> // run with no transaction
> }
>
> public void myMethod() {
> // uses @Transactional(MANDATORY)
> }
> }
>
> @Transactional(MANDATORY)
> public class MyOtherBean {
> @PostConstruct
> @Transactional(REQUIRES_NEW)
> public void postConstruct() {
> // run with a new transaction
> }
>
> public void myMethod() {
> // uses @Transactional(MANDATORY)
> }
> }
>
> 2. @PostConstruct is like any other method and inherits the class-level
> transaction attribute, but the developer must override the
class-level
> attribute in some cases.
>
> @Transactional(MANDATORY)
> public class MyBean {
> @PostConstruct
> public void postConstruct() {
> // FAILS because there can be no existing
transaction context
> }
>
> public void myMethod() {
> // uses @Transactional(MANDATORY)
> }
> }
>
> @Transactional(MANDATORY)
> public class MyOtherBean {
> @PostConstruct
> @Transactional(REQUIRES_NEW)
> public void postConstruct() {
> // run with a new transaction
> }
>
> public void myMethod() {
> // uses @Transactional(MANDATORY)
> }
> }
>
> 3. @PostConstruct is like any other method and inherits the class-level
> transaction attribute, but methods (like lifecycle callbacks) for
> which there can be no preexisting transaction context are handled as
> if they were REQUIRES_NEW when the MANDATORY attribute is specified
> (i.e., the attribute value handling here is special-cased).
>
> @Transactional(MANDATORY)
> public class MyBean {
> @PostConstruct
> public void postConstruct() {
> // runs with a new transaction
> }
>
> public void myMethod() {
> // uses @Transactional(MANDATORY)
> }
> }
>
> @Transactional(MANDATORY)
> public class MyOtherBean {
> @PostConstruct
> @Transactional(REQUIRES_NEW)
> public void postConstruct() {
> // run with a new transaction, same as
above
> }
>
> public void myMethod() {
> // uses @Transactional(MANDATORY)
> }
> }
>
> 4. @PostConstruct can never be transactional. UserTransaction can be
> used explicitly in the @PostConstruct method if needed.
>
> @Transactional(MANDATORY)
> public class MyBean {
> @PostConstruct
> public void postConstruct() {
> // runs with no transaction context
> }
>
> public void myMethod() {
> // uses @Transactional(MANDATORY)
> }
> }
>
> @Transactional(MANDATORY)
> public class MyOtherBean {
> @PostConstruct
> @Transactional(REQUIRES_NEW)
> public void postConstruct() {
> // @Transactional is either ignored or
causes runtime failure
> }
>
> public void myMethod() {
> // uses @Transactional(MANDATORY)
> }
> }
>
>
> #1 is most similar to stateful session beans in the current version of
> the EJB spec. When the ability to have transactional @PostConstruct
> methods on stateful session beans was added to the EJB spec, it
> couldn't be done by default due to compatibility.
>
> #3 is consistent with Singletons in the current version of the EJB spec.
>
> #4 is most similar to previous versions of the EJB spec.
>
> We're currently leaning towards #3, since it seems consistent with other
> interceptor use, but good arguments can be made for any of these
choices.
> We really need your feedback.
>
> Let us know which choice you prefer before Friday, March 15.
>
> Thanks.