Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebSphereUowTransactionManager causes exception for PROPAGATION_SUPPORTS when timeout is specified #25132

Closed
fralalonde opened this issue May 26, 2020 · 8 comments
Assignees
Labels
in: data Issues in data modules (jdbc, orm, oxm, tx) status: backported An issue that has been backported to maintenance branches type: bug A general bug
Milestone

Comments

@fralalonde
Copy link

fralalonde commented May 26, 2020

Context

We're upgrading a legacy app from Spring 1.2.8 (yes, for real) to Spring 4.3.6, following best practices and settings things right as we move along. We have everything working up to here except for this bug which required investigation and for which this is the report. Tested on WebSphere 8.5.5 and 9.0. We can't move to Spring 5 yet because of a remaining dependence on Java 7, but I'd be expecting the same behavior from it after looking at the Spring code.

Details

The app is using XML configuration with per-method transaction management declared like so:

<tx:jta-transaction-manager />
[...]
<bean id="SomeApplicationBean" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager"><ref bean="transactionManager"/></property>
    [...]
    <property name="transactionAttributes">
        <props>
            <prop key="getQuestionsList">PROPAGATION_REQUIRED,timeout_60</prop>

Under Spring 4, this results at runtime in WebSphere throwing an exception:

 java.lang.IllegalArgumentException: Invalid UOW type: 0
     at com.ibm.ws.uow.UOWManagerImpl.setUOWTimeout(UOWManagerImpl.java:706)
     at org.springframework.transaction.jta.WebSphereUowTransactionManager.execute(WebSphereUowTransactionManager.java:286)

Explanation

After investigation, it turns out that Spring's JtaTransactionManager tries to use the WebSphere Local Transaction manager (UOW_TYPE_LOCAL_TRANSACTION) whenever possible. However, the WAS Local Transaction manager does not support timeouts.

Excerpt from IBM's javadoc:

Throws:
java.lang.IllegalArgumentException - Thrown if the specified type of UOW does not support timeout, e.g. UOW_TYPE_LOCAL_TRANSACTION.

Why it worked before

The Spring 1.2 transaction management was exclusively using the Global Transaction manager, which accepts the declared timeout with no issue.

Workaround

For now, we'll be using our own custom copy of WebSphereUowTransactionManager that'll d avoid using UOW_TYPE_LOCAL_TRANSACTION whenever a timeout is specified for the transaction. Obviously, a baked-in fix would be preferable, I am willing to supply a PR to that effect, although it would be initially against the 4.3 branch.

We'll also be reviewing our declared timeouts for most operations but it is unlikely that we'll get rid of them all.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label May 26, 2020
@jhoeller jhoeller self-assigned this May 26, 2020
@jhoeller
Copy link
Contributor

It's not clear to me why UOW_TYPE_LOCAL_TRANSACTION would be used for actual transactions here; we're only really using it to wrap a transaction boundary in PROPAGATION_SUPPORTS scenarios. Is that where you're hitting the timeout problem, or are you running into it for actual PROPAGATION_REQUIRED declarations?

@jhoeller
Copy link
Contributor

Also, I suppose you've been using the plain JtaTransactionManager before, with no need for transaction suspension support on WebSphere? Could you keep using that variant for the time being, ignoring WebSphereUowTransactionManager and its different kind of interaction model completely?

@fralalonde
Copy link
Author

The error actually occurs with an operation marked as PROPAGATION_SUPPORTS and not PROPAGATION_REQUIRED as my example implied.

Your observation is very useful as it reduces considerably the number of operations we'd have to review - I only count a handful actual occurences of PROPAGATION_SUPPORTS, some of which already do not specify a timeout.

@jhoeller
Copy link
Contributor

jhoeller commented May 26, 2020

Please note that timeouts are generally only designed for PROPAGATION_REQUIRED and PROPAGATION_REQUIRES_NEW, and not meant to be set for any other propagation level (as documented in TransactionDefinition and the @Transactional annotation). Other transaction manager implementations simply ignore a timeout completely other than for an actual transaction begin.

So the bug in WebSphereUowTransactionManager is that it shouldn't even try to call setUOWTimeout in the UOW_TYPE_LOCAL_TRANSACTION case; it's missing an extra condition on the if statement there. However, the application also shouldn't even declare a timeout on such scopes to begin with since a timeout will never actually be in effect there.

From that perspective, you could simply drop all timeout clauses for PROPAGATION_SUPPORTS definitions in your codebase. Those arguably should never have been there in the first place since they do not have an actual effect with any transaction manager implementation in any version of Spring, as far as I can tell. JtaTransactionManager used to ignore those in Spring 1.2 as well.

@jhoeller jhoeller added in: data Issues in data modules (jdbc, orm, oxm, tx) type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels May 26, 2020
@jhoeller jhoeller added this to the 5.2.7 milestone May 26, 2020
@fralalonde
Copy link
Author

I vaguely remember using a plain JtaTransactionManager before switching to the standard <tx:jta-transaction-manager />. I was expecting we'd somehow benefit from the WebSphere-specific implementation. Forcing usage of the JtaTransactionManager would be an option, as we actually have little to no WebSphere-specific code of our own (to my knowledge).

Also, I've already raised some doubts within our team as to actual benefits of these timeouts. I've seen the pattern of "leave no property unset / no feature unused" in more than a few places, and I am willing to investigate some these to simplify things.

Also, thank you. Your quick intervention was most unexpected and quite welcome.

@jhoeller
Copy link
Contributor

jhoeller commented May 26, 2020

No problem, good to hear this is helpful. We are going to refine the timeout applicability in WebSphereUowTransactionManager in our upcoming 5.2.7 release and also in our next round of backports. That said, it doesn't look like you'll have to wait for any such patch of ours. Forcing usage of a plain JtaTransactionManager should be a clean way out here, and/or dropping the inapplicable timeout clauses from your PROPAGATION_SUPPORTS definitions (which is generally sensible since those timeouts are otherwise misleading in the code since they'll never have actual effect in a SUPPORTS definition).

@fralalonde
Copy link
Author

Yes. I've understood what you meant about timeouts being useless in those cases. Adding the weight of your argument here should help me tip the balance in favor of removing them.

As a general note, upgrading from version to 1 to version 4 was incredibly straightforward - no big surprises. I'm a long time user and Spring still astounds me, both in technology and process. Looking forward to use version 5 and beyond, in both old and new projects.

@jhoeller jhoeller changed the title WebSphereUowTransactionManager causes exception using Local Transaction when Timeout is specified WebSphereUowTransactionManager causes exception for PROPAGATION_SUPPORTS when timeout is specified May 26, 2020
@jhoeller
Copy link
Contributor

Let's keep this issue open for my planned refinement in WebSphereUowTransactionManager timeout applicability, aligning it with the timeout handling in other transaction manager implementations. A reference back to your original upgrade hurdle here is very useful for that purpose. Thanks for the report, in any case!

Good to hear that the upgrade was so straightforward in general...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: data Issues in data modules (jdbc, orm, oxm, tx) status: backported An issue that has been backported to maintenance branches type: bug A general bug
Projects
None yet
Development

No branches or pull requests

3 participants