Sorry for the late reply to this, we have been trying to put some things
together behind the scenes...
It seems to me the primary issue here is the lack of use-cases driving the
motivation for the proposal/focusing the discussion. Nigel did a great job
of summarizing them here:
http://java.net/projects/jms-spec/pages/JMSContextScopeUseCases. The
use-cases for the JMS context I think presents a good super-set of how the
transaction scope is likely used.
As to use-cases beyond JTA vs. sticking to JTA, I think I'd prefer Pete
weigh in on this. My standpoint remains that this should not be a focus for
CDI since CDI is primarily a Java EE centric API and JTA is the standard
transaction management API for Java EE. As to defining declarative
transaction management annotations, that is being done in the JTA/Java EE
spec (please check the recent archives for the Java EE EG). The annotations
are clearly JTA centric. Regardless, the transaction scope can be defined
completely separate of the higher level transaction management semantics as
long as one sticks to JTA (which the current proposal does).
As to the current wording of the proposal, I've asked Pete to take a look at
this. As I've suggested, your points are unclear to me and I would certainly
welcome a concrete alternate proposal.
Hope this helps matters (particularly Nigel's use-cases).
I would like to get a general idea on the possibility of including this
scope in CDI 1.1. If this is not possible, the most prudent path for JMS
would be to define this life-cycle as part of JMS 2 and leave the CDI EG be
(much like the life-cycle of JPA being defined in a self-contained manner).
In my opinion this would be a shame and a failure of due collaboration
between the JMS and CDI EGs...
-----Original Message-----
From: Mark Struberg [mailto:struberg@yahoo.de]
Sent: Sunday, May 27, 2012 7:14 AM
To: Reza Rahman; cdi-dev(a)lists.jboss.org
Subject: Re: [cdi-dev] Transaction Scope for CDI
Hi Reza, all!
Sorry for the delay (pretty busy times right now). Response inline.
LieGrue,
strub
----- Original Message -----
> From: Reza Rahman <reza_rahman(a)lycos.com>
> To: cdi-dev(a)lists.jboss.org
> Cc:
> Sent: Wednesday, May 23, 2012 8:18 PM
> Subject: Re: [cdi-dev] Transaction Scope for CDI
>
> Responses in-line...
>
>> -----Original Message-----
>> From: cdi-dev-bounces(a)lists.jboss.org
> [mailto:cdi-dev-bounces@lists.jboss.org]
>> On Behalf Of Mark Struberg
>> Sent: Wednesday, May 23, 2012 5:15 AM
>> To: cdi-dev(a)lists.jboss.org
>> Subject: Re: [cdi-dev] Transaction Scope for CDI
>>
>>
>>
>>
>>
>> Hi!
>>
>> It's really hard to follow (and subsequently check the necessity)
> because
> you
>> didn't gave _reasons_ for all the behaviour.
>
> [Reza Rahman] That's fair and something I anticipated. The problem is
> that it would be a bit odd to discuss all the supporting use-cases in
> the spec itself since the others do not. We can certainly do that here
> (to a great degree Nigel, I and Pete already have) and maybe add to
> the spec if we deem it necessary.
>
>>
>>
>> E.g.
>>
>> > If a contextual object is placed into the transaction context
>> >while a transaction is active, the object will remain available
>> >until the transaction is committed or rolled-back.
>>
>>
>> What about nested transactions? That would then Clash with the
> NormalScoped
>> definition.
>
> [Reza Rahman] Can you kindly elaborate? As such, JTA does not allow
> nested transactions. What it does allow is one or more suspended
> transactions in the same call-stack. In case of CMT, this would be a
> non-issue since the contextual objects would not be propagated beyond
> method invocation boundaries. In case of BMT, you really can't suspend
> the transaction, so this would work there as well?
[strub]
EJB supports REQUIRES_NEW. Now for the wording it's something different
saying
"If a contextual object is placed into the transaction context while a
transaction
is active"
and
"A contextual instance is active AS LONG as the transaction is active"
But then again, you will just repeat the basic definition of a Context. It
would
be
much easier to just define the lifecycle boundaries of the
TransactionContext.
See the wording of the CDI spec 6.7. "Context management for
built-in
scopes"
>> Imo the wording is way too abstract. I know this is really hard stuff
to
> get right
>> and I'd like to thank you for picking this up.
>
> [Reza Rahman] Could you be more specific? That would be helpful in
making
> this more concrete.
>
>> But I share Lincolns sentiments that
>> CDI is NOT the right place to define this.
>
> [Reza Rahman] If a significant portion of this EG feels this way, we can
> certainly get this clarified by Bill, Linda, et al. My suspicion is that
> although this might not be the ideal place, it is likely the most
pragmatic
> place. Either way, it would be good to vet out the technical
aspects of
the
> proposal with CDI centric folks.
[strub]
To me it seems that the proposed wording solely targets JTA use cases. And
this
is imo way too narrow.
Imo we should start with summing up the supported use cases and the parts
we
need for it:
Needed 'parts'
* @Transactional annotation
* TransactionInterceptor implementation
* @TransactionScoped
anything else?
Supported use cases:
* 1.) JTA Extended EM with UserTransaction
* 2.) JTA Container Managed EM in @Stateless EJBs
* 3.) JTA Container Managed EM in Message Driven Beans (do we need to
distinguish between 2. and 3. ?)
* 4.) CDI produced 'native'/'unmanaged' EntityManager
* 5.) Container managed EM injected in CDI beans
* 6.) Container managed EM injected in JSF managed beans
* various mixed scenarios of 2.) .. 4.)
anything else?
Once we agree on those lists, THEN we can discuss about the implementation
details!
Sidenote: in CODI (and DeltaSpike) we implemented this via 1 single
Interceptor
implementation which injects a @Dependent PersistenceStrategy which
the
user
can switch via <alternatives>. Not sure though if we could
specify it
exactly that
way.
>> You can definitely spare the whole paragraph above (not only the quoted
> parts,
>> but the whole one), because this is automatically defined if you
describe
> the
>> lifecycle of the @TransactionScoped beans. Ie WHEN does the context
start,
>> WHEN does the context end and WHEN is the context
active/inactive
>> inbetween.
>
> [Reza Rahman] Hmm - not sure what you mean? Could you kindly propose
> alternate text? If anything I felt I was writing too little...
[strub]
see my comment above regarding the wording in CDI spec 6.7. "Context
management for built-in scopes"
>>
>> Also your wording doesn't cover what happens if there is a method
> invocation
>> with TransactionAttributeType.REQUIRES_NEW ?
>> In this case the original @TransactionScoped should become isActive()
> ==false
>> and a new one should be opened, isn't?.
>
> [Reza Rahman] I avoided calling out specific CMT cases to keep this
compact.
> The use-case is handled though if you trace it through. In the
REQUIRES_NEW
> case, if there is an existing transaction, it would be suspended
and
hence
> any contextual instances that belong to it would not be
propagated past
the
> new method invocation. If there wasn't an existing
transaction, the case
> would be relatively straight-forward -- the instance would be created
and
> placed into the transactional cache. In addition, it will
propagated to
the
> end of the method call to handle the BMT/short-transaction
use-case.
[strub]
See my note above 'set as active' vs 'active if'
>>
>> Also it's way too much fixated to JTA. There is a world outside of JTA
> :)
> Actually
>> most apps do NOT use JTA at all...
>
> [Reza Rahman] It is true that this is deliberately focused on JTA. The
basic
> reason for this is ease of standardization since the JTA
semantics are
> known. If the JTA case can be standardized, I imagine one could tackle
the
> case of other transaction management APIs down the line if
theirs APIs
are
> also adequately standardized as far as CDI/Java EE is concerned.
Also,
> personally I am a supporter of JTA and see few technical reasons to
avoid
> it's use. Nevertheless, I deliberately tried to keep that
possibility
open
> (not the parenthetical remark about CMT/BMT==JTA).
[strub]
To be honest, JTA semantics are blurry to most users and often completely
container depending (when it comes to the gory details you need in big
apps).
JTA is also really imposing heavy limitations to users, e.g. that you
cannot
serialize open JTA transactions and there is also no portable way to
propagate
JPA entity state across clusters when serialisation kicks in. Due to
this
restriction
a LOT projects either use DAOs in their JSF backing beans or do NOT
use
JTA at
all...
>> Also please s/contextual object/Contextual Instance/ as this is a well
> defined
>> terminus tecnicus in the spec.
>
> [Reza Rahman] Again, could you kindly propose specific alternate text?
That
> would be greatly helpful.
[strub]
It's really just s/contextual object/Contextual Instance/
See 6.5, especially 6.5.2. "Contextual instance of a bean"
"Contextual Instance" is a well defined technical term in the CDI spec.
>> > Transactional contexts that come into effect in
>>
>> > complete absence of a transaction
>> > are shared between all contextual objects in a single
>>
>> > managed bean method call
>>
>>
>> a.) you have a chicken egg problem if you e.g. try to @Produces
>> @TransactionScoped EntityManager and you do not yet have an open
>> UserTransation
>
> [Reza Rahman] Not sure I follow? The way it is specified, the object
would
> be created and propagated across the method call. Any
transactions that
> become active after the object is created can still be utilized by the
> instance?
[strub]
We must take care to not implicitely introduce a cyclic reference which
creates a
chicken-egg problem. E.g. a @TransactionScoped bean cannot
open/control a
UserTransaction.
>
>> b.) imo if there is no open Transaction HANDLER then the
> Context#isActive()
>> shall return false, and accessing a Contextual Reference for a
>> @TransactionScoped bean will lead to a ContextNotActiveException.
>
> [Reza Rahman] Right. This was the initial implementation/concept in
Resin.
> The trouble is that it is severely limiting for BMT and cases
where
there is
> no active transaction. For example, the JPA entity manager can
be used
> outside of an active transaction as long as you stick to "read-only"
> methods: . The case in the JMS context is even broader since you can use
the
> JMS APIs without a transaction (even within Java EE).
[strub]
I see. This is targeted for 'auto transactions' which get created if a
user
is
executing a query _without_ calling
em.getTransaction().begin()/commit().
Please note that there is still a transaction in place - it's just not
controlled by the
user. But the wording only fits the @Stateless EJB use case. All
other use
cases
outlined above would imo be broken with the very wording.
"Similarly, contextual objects can outlive method invocation boundaries if
a
transaction spans multiple method calls." is especially very
dangerous
imo. How
would you implement this? I fear this behaviour would be nice for
some use
cases and completely fuck up other ones.
>> > Note that each managed bean method call begins and ends its own
>> > separate local context.
>> certainly not true for nested bean method calls...
>
> [Reza Rahman] Not sure what you mean? Limiting propagation to method
> boundaries was specifically designed to avoid sticky situations where
> transactions may be suspended/activated on the same thread multiple
times.
[strub]
But that doesn't work in practice. Usually only the outermost
@Transactional
(implicite or explicite) method call will 'open' the
transaction context.
It might
get suspended when you call a method with
TransactionAttributeType.REQUIRES_NEW, but usually it just remains open.
>> > Note also that most Container-Managed Transactions
>>
>> > (CMT) span one or more manage bean method calls.
>>
>>
>> I don't get that. Once your EJB method invocation returns, the built in
> EJB-
>> transaction-handler will commit that stuff and even close the involved
>> EntityManager (I'm talking about the REAL native EM and NOT the
>> EntityManager facade you might see as user).
>
> [Reza Rahman] Right, but the point is that CMT transactions can and do
> indeed span multiple method calls (e.g. is transaction propagation is
set to
> REQUIRED or SUPPORTS). In such a case, the context would ensure
that all
> methods in a the call-stack participating in the transaction are
referring
> to the same instance.
>
>>
>> Au contraire with an Extended EM, you might open the UserTransaction in
a
> JSF
>> backing bean and keep it open during multiple @Stateless service
> invocations,
>> finally closing the UserTransaction before the JSF action returns.
>
> [Reza Rahman] Yes, propagating instances across the transaction would
handle
> this the way it is described now. BTW, for JPA in particular, you are
> actually not allowed to propagate EMS from stateful to stateless
contexts:
>
http://docs.jboss.org/hibernate/entitymanager/3.5/reference/en/html/architec
> ture.html (not a reasonable restriction IMO).
[strub]
I've not written anything about @Stateful. The JSF managed bean spec
defines
that @PersistenceContext might get injected. It doesn't say
anything about
those restrictions.
PS: This is only true for container managed EntityManagers anyway...
PPS: The doc you mentioned only covers container managed EMs, thus leaving
out a wide share of productive projects which create and manage the EM
themselfs. E.g. almost all Spring based apps, and lots of others. I prefer
to
reference the JSR specs instead (despite they are much harder to read
than
the
really good JBoss documents).
>> Of course those are only first 'feelings' and I certainly need more
> time
> to get
>> warm with the wording.
>
> [Reza Rahman] Right -- I fully expect that and is the reason I will
likely
> need to tend to this discussion for a duration (which is fine).
The
issues
> you raised are good conversation starters. Alternatively, we
could start
> with a bunch of use-cases and see how the proposal fits? Luckily, we do
> already have those for the proposed JMS 2 context (maybe Nigel can
oblige
> here?). Also, I could pose some pseudo-code for the proposal
(tends to
be
> easier to follow since it provides conditional structures which
natural
> language does not).
[strub]
+1 for use cases. In CODI, TomEE, Seam-Persistence we already have a few
@Transactional implementations.
Please note that there are quite a few patterns out there which are _not_
working on clusters! This is also because JPA has a few fundamental flaws
which
I like to get fixed as well (see JPA_SPEC-21).
I'm not sure if we can deliver a 1-fits-it-all logic. This might depend
heavily
on
how the user works within his application.