14

We are in the process of upgrading from JBoss 6 to JBoss 7. The nature of our application has a separate database instance per customer, as well as a core configuration database common to all customers. We often have EJB code which will at least reference the core database plus the individual customer's data in one call, and even some general background processes that go through all customers.

In JBoss 6 this was handled without issue by setting the method with a NOT_SUPPORTED transaction attribute. However, JBoss 7 complains about this with the following error:

ARJUNA012140: Adding multiple last resources is disallowed. Trying to add LastResourceRecord(XAOnePhaseResource(LocalXAResourceImpl@74bec54d[connectionListener=d3ce980 connectionManager=25b47a05 warned=false currentXid=< formatId=131077, gtrid_length=29, bqual_length=36, tx_uid=0:ffff0a2c28d1:-5a4c1f9a:504689c9:11, node_name=1, branch_uid=0:ffff0a2c28d1:-5a4c1f9a:504689c9:14, subordinatenodename=null, eis_name=unknown eis name >])), but already have LastResourceRecord(XAOnePhaseResource(LocalXAResourceImpl@518d0191[connectionListener=1a05d94a connectionManager=135f1cfe warned=false currentXid=< formatId=131077, gtrid_length=29, bqual_length=36, tx_uid=0:ffff0a2c28d1:-5a4c1f9a:504689c9:11, node_name=1, branch_uid=0:ffff0a2c28d1:-5a4c1f9a:504689c9:13, subordinatenodename=null, eis_name=unknown eis name >]))

How can we work around this problem without wrapping every call to the different databases in a separate EJB call and transaction. Is there a way to actually turn off the JBoss transaction management in an EJB call or something similar?

Note: This question was modified after the bounty started based on additional discovery to sharpen the focus on the specific problem and remove other possibilities that were excluded.

Yishai
  • 90,445
  • 31
  • 189
  • 263
  • 1
    I found this. https://venugopaal.wordpress.com/2009/02/11/jboss5-adding-multiple-last-resources-is-disallowed/. Related? – pd40 Sep 09 '12 at 13:33

2 Answers2

19

Two suggestions:

  1. Consider updating the datasources to their XA equivalents. This will solve all your problems. I suspect you are hindered here?
  2. Consider setting com.arjuna.ats.arjuna.allowMultipleLastResources to true in the server conf. This will allow the behaviour you want, but unfortunately for the whole app, not just the method.

Update:

I don't recommend enabling multiple one-phase resources since it weakens the transactional properties of you app substantially. But if you want to do this in JBoss 7 you need to modify standalone.xml and add:

<system-properties>
        <property name="com.arjuna.ats.arjuna.allowMultipleLastResources" value="true"/>
</system-properties>

You now have a system which is not far away from one without transactions. What it will still do though, is to warn you if you get heuristic outcomes.

My recommendation is still to use XA datasources if you can.

Update 2:

Oh, and if someone comes along to read this I want to add that if you can divide your code into different methods, unlike the OP, I would recommend restructuring your code and use @TransactionAttribute(REQUIRES_NEW) to create parallel transactions. This is better than turning on multiple 1PC, albeit not as good as turning on XA.

Alexander Torstling
  • 18,552
  • 7
  • 62
  • 74
  • Thanks. We plaid with XA, but it didn't work (that was probably a failure on our part), but it was anyway the wrong solution, so we didn't push in that direction. Where is allowMultipleLastResources in JBoss 7, we couldn't find it? – Yishai Sep 11 '12 at 17:17
  • we ended up going with the bean managed transaction fix. Yes the requires new is the obvious solution (that is what we thought about but did not want to do). Thanks for the info on where to set allowMultipleLastResources, that wasn't easy to find, but we aren't using it. – Yishai Sep 12 '12 at 18:14
  • When using **allowMultipleLastResources** beware that it may lead to the transaction being committed on some of your datasources and not for others, if the transaction is rolled back for one of them. See https://developer.jboss.org/wiki/Multiple1PC – GreenGiant Mar 03 '16 at 16:12
10

OK, it turns out that unlike JBoss6, a NOT_SUPPORTED transaction is still a transaction as far as the validation logic for retrieving data sources is concerned.

The way to work around this is to make the whole EJB a bean managed transaction:

@TransactionManagement(TransactionManagementType.BEAN)

This unfortunately limits some flexibility in that some times you would rather control this method-by-method, but it isn't too painful a workaround.

Yishai
  • 90,445
  • 31
  • 189
  • 263