-
1. Re: JBAS-7507: UserTransaction & Nested Transactions
jiwils Dec 10, 2009 6:11 PM (in response to jiwils)"Dimitris Andreadis" wrote:
Is org.jboss.tm.usertx.server.UserTransactionSession used solely for remote client UserTransactions or are there other call paths to it that would be valid otherwise, e.g. BMT in the server side implementing something like REQUIRES_NEW.
Should throwing an exception be configurable in ClientUserTransactionService, with the default being 'true'? -
2. Re: JBAS-7507: UserTransaction & Nested Transactions
dimitris Dec 16, 2009 8:54 AM (in response to jiwils)Assuming we are going to throw a NotSupportedException, it's not clear to me where this exception should originate: On the client side or the server side?
Can org.jboss.tm.usertx.server.UserTransactionSessionImpl detect an existing transaction is associated with the client-side thread?
-
3. Re: JBAS-7507: UserTransaction & Nested Transactions
vickyk Dec 18, 2009 4:34 AM (in response to dimitris)I did spend some time looking at the code implemetation, I am yet to conclude things.
I did see the ClientUserTransaction(CUT) being bound to JNDI here
ctx.bind(JNDI_NAME, ClientUserTransaction.getSingleton());
At the remote client side I can get the CUT by looking at "UserTransaction" object e.g ctx.lookup("UserTransaction")
[java] org.jboss.tm.usertx.client.ClientUserTransaction@15663a2
However when I make any invocation from ut it does not go through
but it invokes invoke(..) in
I am in process of understanding the flow yet, may be someone can give quick pointers .
What am I missing in understanding the flow?
-
4. Re: JBAS-7507: UserTransaction & Nested Transactions
aloubyansky Dec 19, 2009 8:30 AM (in response to jiwils)"Dimitris Andreadis" wrote:
Is org.jboss.tm.usertx.server.UserTransactionSession used solely for remote client UserTransactions or are there other call paths to it that would be valid otherwise, e.g. BMT in the server side implementing something like REQUIRES_NEW.AFAICS it is used only for remote clients.
EJBs use org.jboss.ejb.EnterpriseContext$UserTransactionImpl, servlets - org.jboss.tm.usertx.client.ServerVMClientUserTransaction.
None of these implementations checks whether there already exists an active transaction associated with the thread. So, if it has to be checked it has to be done in every impl or in the TransactionManager impl.
As to the REQUIRES_NEW or whatever call path that leads to a nested transaction, at the end it would still be a nested transaction which is not supported. So, there are two choices:
1. throw an exception
2. suspend the currently active transaction, start a new one and when it ends resume the suspended one, like it's done in CMT for REQUIRES_NEW.
-
5. Re: JBAS-7507: UserTransaction & Nested Transactions
aloubyansky Dec 19, 2009 9:17 AM (in response to vickyk)I guess for remote clients it could be fixed in two places:
- UserTransactionSessionImpl on the serverside
- or probably even better on the client side in ClientUserTransaction
C:\Users\avoka\svn.jboss.org\jbossas\branches\JBPAPP_4_2_0_GA_CP\server>svn diff Index: src/main/org/jboss/tm/usertx/server/UserTransactionSessionImpl.java =================================================================== --- src/main/org/jboss/tm/usertx/server/UserTransactionSessionImpl.java (revision 93372) +++ src/main/org/jboss/tm/usertx/server/UserTransactionSessionImpl.java (working copy) @@ -44,6 +44,7 @@ import org.jboss.logging.Logger; import org.jboss.tm.TransactionPropagationContextFactory; import org.jboss.tm.TransactionPropagationContextUtil; +import org.jboss.tm.TxUtils; import org.jboss.tm.usertx.interfaces.UserTransactionSession; import org.jboss.util.collection.WeakValueHashMap; @@ -128,11 +129,20 @@ SystemException { TransactionManager tm = getTransactionManager(); + + Object tpc = getTPCFactory().getTransactionPropagationContext(); + Transaction currentTx = (Transaction) activeTx.get(tpc); + // int status = tm.getStatus(); <-- this doesn't work here + // int status = currentTx == null ? Status.STATUS_NO_TRANSACTION : currentTx.getStatus(); <- this does + // System.out.println(TxUtils.getStatusAsString(status)); + if(currentTx != null) + throw new NotSupportedException("Attempt to start a nested transaction (the transaction started previously hasn't been ended yet)."); + // Set timeout value tm.setTransactionTimeout(timeout); // Start tx, and get its TPC. tm.begin(); - Object tpc = getTPCFactory().getTransactionPropagationContext(); + // Suspend thread association. Transaction tx = tm.suspend(); // Remember that a new tx is now active. Index: src/main/org/jboss/tm/usertx/client/ClientUserTransaction.java =================================================================== --- src/main/org/jboss/tm/usertx/client/ClientUserTransaction.java (revision 93372) +++ src/main/org/jboss/tm/usertx/client/ClientUserTransaction.java (working copy) @@ -113,6 +113,10 @@ public void begin() throws NotSupportedException, SystemException { + int status = getStatus(); + if(status != Status.STATUS_NO_TRANSACTION) + throw new NotSupportedException("Attempt to start a nested transaction (the transaction started previously hasn't been ended yet)."); + ThreadInfo info = getThreadInfo(); trace = log.isTraceEnabled(); // Only check for trace enabled once per transaction
-
6. Re: JBAS-7507: UserTransaction & Nested Transactions
aloubyansky Dec 19, 2009 10:15 AM (in response to jiwils)From the issue description:
check org.jboss.tm.usertx.server.UserTransactionSessionImpl::begin(.)
**************************************************************
Transaction tx = tm.suspend();
**************************************************************
This suspension of the ongoing tx had resulted in not throwing NotSupportedException.This is actually true. If tm.resume(tx) is called after the suspension (and commented out in commit(tpc) and rollback(tpc)) then subsequent ut.begin() will fail with NSE:
16:06:31,730 ERROR [STDERR] javax.transaction.NotSupportedException 16:06:31,730 ERROR [STDERR] at com.arjuna.ats.internal.jta.transaction.arjunacore.BaseTransaction.begin(BaseTransaction.java:79) 16:06:31,730 ERROR [STDERR] at com.arjuna.ats.jbossatx.BaseTransactionManagerDelegate.begin(BaseTransactionManagerDelegate.java:77) 16:06:31,730 ERROR [STDERR] at org.jboss.tm.usertx.server.UserTransactionSessionImpl.begin(UserTransactionSessionImpl.java:147) 16:06:31,730 ERROR [STDERR] at org.jboss.tm.usertx.server.ClientUserTransactionService.invoke(ClientUserTransactionService.java:112)
So the TM impl has this logic. The problem is you can't keep client tx associated with the serverside thread.
-
7. Re: JBAS-7507: UserTransaction & Nested Transactions
vickyk Dec 19, 2009 7:55 PM (in response to vickyk)vickyk wrote:
What am I missing in understanding the flow?
After spending more time I managed to find the reason and came up with this change, it is client side validation.
[vicky@posh client]$ svn diff Index: ClientUserTransaction.java =================================================================== --- ClientUserTransaction.java (revision 93943) +++ ClientUserTransaction.java (working copy) @@ -107,7 +107,15 @@ throws NotSupportedException, SystemException { ThreadInfo info = getThreadInfo(); - + + int txCount = getTxSpanned(); + if(txCount > 0) + { + // Rollback the earlier tx ! + rollback(); + // Throw Not supported TX Exception. + throw new NotSupportedException("Nested Transaction is not supported for remote standalone Client"); + } try { Object tpc = getSession().begin(info.getTimeout()); @@ -311,7 +319,7 @@ Reference ref = new Reference("org.jboss.tm.usertx.client.ClientUserTransaction", "org.jboss.tm.usertx.client.ClientUserTransactionObjectFactory", null); - + return ref; } @@ -401,6 +409,11 @@ return ret; } + private int getTxSpanned() + { + ThreadInfo info = (ThreadInfo) threadInfo.get(); + return info.getTPCSize(); + } // Inner classes ------------------------------------------------- @@ -496,6 +509,11 @@ { timeout = seconds; } + + int getTPCSize() + { + return tpcStack.size(); + } } }
-
8. Re: JBAS-7507: UserTransaction & Nested Transactions
vickyk Dec 19, 2009 8:07 PM (in response to aloubyansky)alex.loubyansky@jboss.com wrote:
I guess for remote clients it could be fixed in two places:
- UserTransactionSessionImpl on the serverside
- or probably even better on the client side in ClientUserTransaction
Yes the ClientUserTransaction changes are the better option as this would happen on the client side, we must go with it.
I did not check the reponse on forums yesterday so couldn't use your analysis on client side, I have also tested the similar one.
However I see your changes much lesser and simpler than mine, I somehow had overlooked at the ClientUserTransaction::getStatus.
-
9. Re: JBAS-7507: UserTransaction & Nested Transactions
aloubyansky Dec 20, 2009 5:23 AM (in response to vickyk)In general, the failure of a nested transaction should not affect the parent transaction. If we consider second ut.begin() as an attempt to start a nested transaction, its failure shouldn't abort the current one. So, I'd say don't rollback the current one.