简体   繁体   中英

How to enable transactional behavior using Spring XML configuration?

I am studying for Spring Core certification and I have the following doubts related the declarative transacion configuration via XML configuration file .

So I know that I can configure the transactional behavior annotating classes and\\or methods that have to be transactional behavior, something like this:

@Transactional(timeout=60)
public class RewardNetworkImpl implements RewardNetwork {

    public RewardConfirmation rewardAccountFor(Dining d) {
        // atomic unit-of-work
    }

    @Transactional(timeout=45)
    public RewardConfirmation updateConfirmation(RewardConfirmantion rc) {
        // atomic unit-of-work
    }
}

I also know that sometimes I can't use annotations to configure the transactional behavior of classes and\\or methods (for example if I don't have the Java code of a class that contains method that have to work in transactional way).

So I can configure the transactional behavior using XML configuration and AOP .

Reading the documentation I know that I can do it in this way:

  1. An AOP pointcut declares what to advise.

  2. Spring's tx namespace enables a concise definition of transactional advice.

  3. Can add transactional behavior to any class used as a Spring Bean

And I have the following example related how do it:

<aop:config>
    <aop:pointcut id=“rewardNetworkMethods” expression=“execution(* rewards.RewardNetwork.*(..))”/>
    <aop:advisor pointcut-ref=“rewardNetworkMethods” advice-ref=“txAdvice”/>
</aop:config>

<tx:advice id=“txAdvice”>
    <tx:attributes>
        <tx:method name="get*" read-only="true" timeout="10"/>
        <tx:method name="find*" read-only="true" timeout="10"/>
        <tx:method name="*" timeout="30"/>
    </tx:attributes>
</tx:advice>

<bean id=“transactionManager”
class=“org.springframework.jdbc.datasource.DataSourceTransactionManager”>
    <property name=“dataSource” ref=“dataSource”/>
</bean>

Ok, but now I have some problem to understand what exactly do the previous XML configuration.

I think that the first section represent the declaration of what I want to advice :

<aop:config>
    <aop:pointcut id=“rewardNetworkMethods” expression=“execution(* rewards.RewardNetwork.*(..))”/>
    <aop:advisor pointcut-ref=“rewardNetworkMethods” advice-ref=“txAdvice”/>
</aop:config>

So in this case I am declaring a pointcut related to all the methods inside the rewards.RewardNetwork that take any parameters and that return any kind of object.

So this means that I want to add the transactional behavior at all these methods? or what?

What exactly means the second line of this tag?, this one:

<aop:advisor pointcut-ref=“rewardNetworkMethods” advice-ref=“txAdvice”/>

Then, in the second section, it seems to me that it specify a subset of the metodse selected by the previous pointcut expression and that the transactional behavior is enabled for these methods:

<tx:advice id=“txAdvice”>
    <tx:attributes>
        <tx:method name="get*" read-only="true" timeout="10"/>
        <tx:method name="find*" read-only="true" timeout="10"/>
        <tx:method name="*" timeout="30"/>
    </tx:attributes>
</tx:advice>

In this case I think that it is used the tx namespace to enables a concise definition of transactional advice for:

  • All the methods that begin with get
  • All the metod that begin with find
  • What are selecting with the third tx tag? (*)

It seems to me that first it use AOP to select a pointcut to select a target class and methods on which I want to enable the transactional behavior and then it is used the tx tag to select a subset of specifics methods to make realy transactional.

If it is so why exist this double step to select methos and make it transactional?

Is it right or am I missing something? Can you explain me exactly what is the logic of this configuration?

<aop:advisor pointcut-ref=“rewardNetworkMethods” advice-ref=“txAdvice”/>

This line means that for pointcut defined

<aop:pointcut id=“rewardNetworkMethods” expression=“execution(* rewards.RewardNetwork.*(..))”/>

advice called txAdvise is to be executed. The second part

<tx:advice id=“txAdvice”>
<tx:attributes>
    <tx:method name="get*" read-only="true" timeout="10"/>
    <tx:method name="find*" read-only="true" timeout="10"/>
    <tx:method name="*" timeout="30"/>
</tx:attributes>

is the concrete definition of the tAdvice advice. First there it is clear that the advice is transactional behaviour definition. The * in the txAdvice means everything not matched by the get* and find* lines gets the * definition.

You are right that this configuration allows - but not forces - for certain duplication. In my understanding this is caused by the fact that the first part in the aop namespace is general spring AOP, needed to say which Java functionality needs to be AOP-ed (by default proxied) at all. The second part defines a concrete AOP proxy as tx proxy and allows for fine tuning of the tx behaviour. You cannot put this into the AOP part as the aop namespace is general AOP and knows nothing about transactions. On the other hand fine tuning of tx behaviour at given advice comes oft handy. Typically you would declare the pointcut for all services in a package and then generic tx advice for given method naming pattern (just like in your example). This way you get pretty much uniform and generic tx definition not possible with annotation based definitions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM