Handle nested transactions in transaction-sticky load balance policies
----------------------------------------------------------------------
Key: JBAS-7535
URL:
https://jira.jboss.org/jira/browse/JBAS-7535
Project: JBoss Application Server
Issue Type: Feature Request
Security Level: Public (Everyone can see)
Components: Clustering
Reporter: Brian Stansberry
Assignee: Brian Stansberry
Fix For: JBossAS-6.0.0.CR1
If the client creates a nested transaction, ClientUserTransactionStickyInterceptor
doesn't detect that the TransactionPropagationContext has changed following the
response, and thus doesn't associate the target with the new TPC. Effect is the new
TPC is not sticky.
One possibility is to throw NotSupportedTransaction if we detect a nested transaction. But
from a quick look at this code, it seems easier to support nested transactions than to
throw NotSupportedTransaction. Is it as simple as detecting if the TPC changes from before
and after the invocation and storing the target if it has?
public class ClientUserTransactionStickyInterceptor extends
AbstractTransactionStickyInterceptor
{
@Override
public Object invoke(Invocation invocation) throws Throwable
{
putIfExistsTransactionTarget(invocation);
Object existingTPC = getTransactionPropagationContext(); // NEW
Object response = getNext().invoke(invocation);
invocationHasReachedAServer(invocation, response, existingTPC); //NEW
return response;
}
public void invocationHasReachedAServer(Invocation invocation, Object response, Object
existingTPC)
{
Object tpc = getTransactionPropagationContext();
if (tpc == null || tpc.equals(existingTPC) == false) // NEW
{
/* If tpc is null when invoking a UserTransaction operation, begin()
* is being called, so we remember the target where the transaction
* was started.
*/
rememberTransactionTarget(invocation, response);
}
}
}
I don't much like detecting the nested transaction in advance and throwing an
exception. Certainly not if we *can* support nested transactions; in that case it's
not the interceptors place to decide what the server allows. AFAICT throwing an exception
would require doing something ugly like this on every call
Object existingTPC = getTransactionPropagationContext();
if (existingTPC != null &&
("begin".equals(invocation.getMethod().getName()) &&
invocation.getMethod().getDeclaringClass().equals(UserTransaction.class))
{
throw new NotSupportedTransaction("blah blah blah");
}
putIfExistsTransactionTarget(invocation);
Object response = getNext().invoke(invocation);
invocationHasReachedAServer(invocation, response);
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
https://jira.jboss.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira