如何使用Spring XML配置启用事务性行为?

时间:2014-12-26 12:17:34

标签: java spring transactions spring-transactions

我正在攻读Spring Core认证,我通过 XML配置文件声明式transacion配置有疑问。

所以我知道我可以配置注释类和/或必须是事务行为的方法的事务行为,如下所示:

@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
    }
}

我也知道有时候我不能使用注释来配置类和\或方法的事务行为(例如,如果我不具有包含必须的方法的类的Java代码以交易方式工作)。

所以我可以使用 XML配置 AOP 来配置事务行为。

阅读文档我知道我可以这样做:

  1. AOP切入点声明了建议内容。

  2. Spring的 tx 命名空间可以实现简洁的定义 交易建议。

  3. 可以将事务行为添加到用作的任何类 春豆

  4. 我有以下示例,它们是如何做到的:

    <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>
    

    好的,但现在我有一些问题需要了解以前的XML配置到底做了什么。

    我认为第一部分代表我想要建议的声明

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

    所以在这种情况下,我宣布与 rewardsNwardNetwork 中的所有方法相关的切入点,这些方法接受任何参数并返回任何类型的对象。

    所以这意味着我想在所有这些方法中添加事务行为?或者什么?

    这个标签的第二行究竟是什么意思?,这一个:

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

    然后,在第二部分中,在我看来,它指定了前一个切入点表达式选择的metodse的子集,并且为这些方法启用了事务行为:

    <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>
    

    在这种情况下,我认为使用tx命名空间来实现简洁的定义 交易建议:

    • 所有以get
    • 开头的方法
    • 所有以find
    • 开头的元词
    • 使用第三个tx标签选择什么? (*)

    在我看来,首先它使用AOP选择切入点来选择目标类和方法 我想在其上启用事务行为,然后使用 tx 标记选择特定方法的子集以进行真正的事务处理。

    如果是这样的话,为什么存在这个双重步骤来选择方​​法并使其成为事务性的?

    是对还是我错过了什么?你能解释一下这个配置的逻辑究竟是什么吗?

1 个答案:

答案 0 :(得分:0)

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

此行表示对于切入点定义的

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

将执行名为txAdvise的建议。第二部分

<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>

是tAdvice建议的具体定义。首先,显然建议是事务行为定义。 txAdvice中的*表示get *和find *行不匹配的所有内容都获得*定义​​。

你是对的,这种配置允许 - 但不是强制 - 用于某些复制。在我的理解中,这是由于aop命名空间中的第一部分是通用spring AOP,需要说明哪些Java功能需要AOP-ed(默认代理)。第二部分将具体的AOP代理定义为tx代理,并允许微调tx行为。你不能把它放到AOP部分,因为aop命名空间是一般的AOP,对事务一无所知。另一方面,在给定建议下微调tx行为非常方便。通常,您将为包中的所有服务声明切入点,然后为给定的方法命名模式声明通用tx通知(就像在您的示例中一样)。通过这种方式,您可以获得基于注释的定义无法实现的统一和通用tx定义。