0
votes

I'll try to describe the situation. We have a web service; on each request web service starts a JTA transaction. It performs several database calls through XA datasource within that and calls some other web services (out of transaction context) and also makes a couple of remote EJB calls on other server.

The problem is that container seems to try to involve EJB into transaction (and that seems logical), but in fact I want it to not particpate in that transaction as when it does participate in that transcation it always times out in the final commit phase, but when I exclude EJB call it works fine.

I cann't change EJB implementation and only control web service code. So, my question is: how do I make an EJB call to transaction-aware EJB, but out of my JTA transaction, but still being in JTA transaction for other XA resourse? I hope I made my question clear :).

EDIT: Trying to make it more clear with pseudo-code example:

// Begin transaction
UserTransaction tx = (UserTransaction) ctx.lookup(USER_TRANSACTION);
tx.begin();

// Do some database operations on XA datasource

// Call remote EJB which has transcation attribute set to 'Supports'
AccountInfo account = accountEjb.getAccountInfo(userId, accountId); // <-- Is it possible to make this to be not be part of user transction?

// Do some more database operations on XA datasource

// Commit transaction
tx.commit();
3
why don't you increase the timeout?Michael Wiles
because the problem is not in the timeout, all calls go through just ok within milleseconds, but when transaction is committed in the end it times out, if ejb call is removed from the call sequence, it commits ok. So, I think it actually has to do something with inter-server communication, but not the value of the timeout.Andrey Adamovich

3 Answers

4
votes

You can create another bean with some appropriate transaction attribute. This bean can delegate all calls to the first bean.

Or you can invoke this ejb from another thread.

1
votes

EJB transaction is declarative: for a given deployment of a given EJB, you specify its transaction semantics. The exact EJB can be deployed (under a different name, of course) and you can specify different requirements for that deployment. This is assuming that (a) you at least have the jar for the ejb, and, (b) that the ejb in question is stand alone and doesn't have dependencies on other components, and (c) the developer of the ejb hasn't violated the idea of the declarative transactions and his bean works outside of a transaction context as well.

0
votes

You can create another method with the suitable tx attribute and then call it with through the self-injected proxy (pseudo-code):

@Stateless
public class LocalEJB1 {

    @EJB
    private LocalEJB1 localEJB1;

    @EJB
    private AccountEJB accountEjb;

    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    public AccountInfo callNonTx() { 
        return accountEjb.getAccountInfo(userId, accountId); 
    }

    public void yourCurrentMethod() {
        // Begin transaction
        UserTransaction tx = (UserTransaction) ctx.lookup(USER_TRANSACTION);
        tx.begin();

        AccountInfo account = localEJB1.callNonTx();
        // Do some more database operations on XA datasource

        // Commit transaction
        tx.commit();
    }
}