|I think you are wrong here.
|Quoting JTA 1.0.1 specification, section 3.2.3:
|"A call to the TransactionManager.suspend method
|temporarily suspends the transaction that is
|currently associated with the calling thread.
Ok the spec makes no sense :)
Ok that sentence says nothing about "disassociation" but "suspend the
transaction" . The action is to "suspend" the target the transaction. Which
one? the one that you can retrieve from the thread association.
We don't know what the "suspend" operation is, and it doesn't say anything
about disassociation, however (see below)
|If the thread is not associated with any
|transaction, a null object reference is returned;
ok
|otherwise, a valid Transaction object is returned.
|The Transaction object can later be passed to the
|resume method to reinstate the transaction context
|association with the calling thread.
|The TransactionManager.resume method re-associates
|the specified transaction context with the calling
|thread. If the transaction specified is a valid
This is inconsistent as the "suspend" and "resume" are not symetrical. This
part ONLY talks about association and nothing about "resuming the
transaction". SO that the action done on resume is "associate" thread, the
action done on suspend is "temporaly suspend the transaction".
Do you see the inconsistency.
|transaction, the transaction context is associated
|with the calling thread; otherwise, the thread is
|associated with no transaction."
|
|So thread association *is* done in these methods.
No, in THIS method (resume) nothing is said in "suspend" in fact suspend
cleanly says that it is a "TX" lifecycle event. The spec is non
symetrical...
|Further quoting section 3.2.3:
|"The application server is responsible for ensuring
|that the resources in use by the application are
|properly delisted from the suspended transaction.
Ok end of story. When I finish my invocation in the container I
disassociate the thread that is going in because it could be reused for
another invocation. THIS ISN"T A "SUSPENSION" and I CERTAINLY DON"T WANT
THE JDBC DRIVER TO BE DELISTED, the JDBC driver should remain there since
other threads associated with this transaction will commit/rollback at some
point. Again suspend resume are methods that live in the realm of
"transaction demarcation semantics" thread association doesn't.
We must NOT properly delist the suspended transaction, because the call I am
talking about from the container IS NOT A SUSPENSION OF THE TRANSACTION the
transaction is STILL VERY ACTIVE, it is just a DISASSOCIATION of the thread
to the Transaction.
|A resource delist operation triggers the Transaction
|Manager to inform the resource manager to
|disassociate the transaction from the specified
|resource object (XAResource.end(TMSUSPEND)).
|When the application s transaction context is
|resumed, the application server ensures that the
|resource in use by the application is again enlisted
|with the transaction. Enlisting a resource as a
|result of resuming a transaction triggers the
|Transaction Manager to inform the resource manager
|to re-associate the resource object with the resumed
|transaction (XAResource.start(TMRESUME))."
That is fine that is the semantics of "suspend/resume" we argued and it was
pointed out that there was no support for distributed "suspend/resume".
End of story.
Bottom line: JTA is at best misleading at worst poorly written.
|So JTA says that resource suspension/resumption
|is *not* the responsibility of the JTA
|implementation when suspending/resuming with
|TM.suspend()/TM.resume().
|
|But besides thread association suspension and
|resource suspension, what is in a tx suspension?
|IMO nothing.
ah ah, well ok we don't agree there. In fact the "propagation" we are
talking about does apply in a suspension.
Again imagine the following scenario:
You start a big transaction and you do work. Then you say "before I buy the
car I want to talk to my wife" and so you tell the system "will decide
later" what can teh system do? it can "suspend the transaction" so that the
resource manager of JDBC to the bank approving the loan will not hold to the
transaction and TIME OUT and ROLLBACK in 20 minutes. You clean up the
resources enrolled in teh TX with this suspend call (if distribution, let's
even assume "no distribution" it is irrelevant to the discussion). So you
come back and you say "i buy" and it "RESUMES" the tx and enroll everybody
so that the play can finish with everybody in a transactional aware state.
Now if this was to take place at once? you would time out ...
So what is disassociation? well imagine the stuff is done at once and the 3
components talk in a container. First thread is going through then it calls
another bean, when that bean is done it "disassociates" the thread because
the bank bean is done with this work and moves on the next one, but the
state is still part of the transaction (with a JDBC driver under it). THAT
DISASSOCIATION (that happens 30 times a second) DOESN"T SUSPEND THE
TRANSACTION, it just disassociates a thread in a corner of the application
and transaction. The transaction goes on and commits. Never was there a
"suspend transaction" demarcation in its life cycle.
yes?
|But that leaves *only* thread association
|suspension/resumption to be done in the TM
|suspend()/resume() methods.
yes,
Since there isn't support for the scenario I put above, Ie a clear
understanding of "suspend and resume" and propagation, there is no code to
support that (and no interface to distribute it I understand). So it leaves
Tx association and disassociation, yes. These can legally be different
methods, I argue that they are since as shown above we disassociate
INDENPENDENTLY of the suspend event in the lifecycle.
|> Well please answer clearly where I can associate the thread with the
|> transaction (we do that quite a lot in the containers, all the
|time, almost
|> every entity call)... ***HOW*** do you implement that call, with resume?
|
|Well, I haven't changed any of that code, but
|I would like the container to get rid of any
|non-JTA calls to the TM.
|
|J2EE-RI and JonAS use TM.resume() for this.
"mal de muchos remedio de tontos" (spanish equivalent of "3 trillion flies
eat shit so you too should")
and it's a miss-interpretation of simple facts. JTA is buggy in its text,
blame it on Susan cheung. It was an amazing piece of spec she was trying to
put together in a hurry.
|In both cases, the code is a little hard to
|read because resource suspension/resumption
|is done in the JTA impl (JonAS), or in a
|layer on top of it (J2EE-RI). In neither
|case there is special thread association
|methods.
I agree that the code to do it is a couple of lines if YOU DON'T DO THE
PROPAGATION. Please go ahead and forget this discussion :)
however
|
|But if JTA TM suspend()/resume() do thread
|association only as I am arguing, it would
|not be that bad to use this, would it?
|
it would be bad. A properly implemented suspend will disenlist the
resources... that is wrong.
The only reason it works is because we don't implement 3.2.3 properly. If
the implementation as you claim you did it, doesn't do that propagation then
it is innocuous. A properly implemented TM will disenlist the JDBC driver I
was talking about and when your container calls commits, since the JDBC
driver isn't listening on the TX demarcation, and you have killed part of
teh state of your TX.
yes?
marc
|Best Regards,
|
|Ole Husgaard.
|