Search code examples
springspring-transactionsspring-expression-language

Configurable transaction timeout: set tx:advice/tx:attributes/tx:method/@timeout using Spring EL


I need a configurable transaction timeout according to Spring profiles. So I would like to set tx:advice/tx:attributes/tx:method/@timeout using Spring EL. It works fine when I do a similar setup for an attribute of a tag in the default (beans) namespace, but not in the tx namespace.

It looks like that a schema validation runs before property substitution, or there is no substitution at this place at all:

Line 21 in XML document from class path resource [spring-core-main.xml] is invalid; 
nested exception is org.xml.sax.SAXParseException; lineNumber: 21; columnNumber: 148; 
cvc-datatype-valid.1.2.1: '#{transactionTimeoutSeconds}' is not a valid value for 'integer'.

My configuration looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:tx="http://www.springframework.org/schema/tx" 
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd 
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx.xsd">

    <bean id="transactionTimeoutSeconds" class="java.lang.Integer">
        <constructor-arg value="30" />
    </bean>

    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="*" timeout="#{transactionTimeoutSeconds}" />
        </tx:attributes>
    </tx:advice>

Is it possible to achieve what I want using XML configuration?


Solution

  • It looks like property substitution does not work in this attribute. Finally I solved the problem by putting the whole tx stuff into profiles:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:tx="http://www.springframework.org/schema/tx" 
        xmlns:aop="http://www.springframework.org/schema/aop"
        xsi:schemaLocation="http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans.xsd 
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
            http://www.springframework.org/schema/tx 
            http://www.springframework.org/schema/tx/spring-tx.xsd">
    
      <beans profile="dev">
        <tx:advice id="txAdvice" transaction-manager="transactionManager">
            <tx:attributes>
                <tx:method name="*" timeout="600" />
            </tx:attributes>
        </tx:advice>
      </beans>
      <beans profile="!dev">
        <tx:advice id="txAdvice" transaction-manager="transactionManager">
            <tx:attributes>
                <tx:method name="*" timeout="30" />
            </tx:attributes>
        </tx:advice>
      </beans>