首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring事务管理:使用@Transactional使用AOP (<aop:advisor)

Spring事务管理:使用@Transactional使用AOP (<aop:advisor)
EN

Stack Overflow用户
提问于 2015-03-24 17:35:11
回答 1查看 1.4K关注 0票数 1

我对Spring事务管理感到困惑。在我的应用程序中,我在服务类中使用@ transaction实现了事务管理。我配置了我的spring.xml,就像:

代码语言:javascript
复制
    <beans:bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
            <beans:property name="dataSource" ref="dataSource" />
            <beans:property name="configLocation" value="classpath:hibernate.cfg.xml"/>                              
            <beans:property name="hibernateProperties">
                <beans:props>
                    <beans:prop key="hibernate.dialect">${jdbc.dialect}</beans:prop>
                    <beans:prop key="hibernate.show_sql">false</beans:prop>
                    <beans:prop key="hibernate.hbm2ddl.auto">update</beans:prop>
                </beans:props>
            </beans:property>
        </beans:bean>  
        <!-- Transaction manager -->
            <beans:bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
                <beans:property name="sessionFactory" ref="sessionFactory" />
            </beans:bean> 

如果我像下面这样在配置文件中实现事务管理,而没有在服务类中使用@ transaction:

代码语言:javascript
复制
    <aop:pointcut id="defaultServiceOperation"
            expression="execution(* x.y.service.*Service.*(..))"/>

    <aop:pointcut id="noTxServiceOperation"
            expression="execution(* x.y.service.ddl.DefaultDdlManager.*(..))"/>

    <aop:advisor pointcut-ref="defaultServiceOperation" advice-ref="defaultTxAdvice"/>

    <aop:advisor pointcut-ref="noTxServiceOperation" advice-ref="noTxAdvice"/>

</aop:config>

它能给我带来“交易”的好处吗?有人告诉我,使用@Transactional也是春季AOP的实现。有人能解释我怎么做吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-03-24 21:44:09

不会的。

福利

如果您不需要一些非常指定的需求,或者您没有性能问题,您就不应该重新发明轮子。Spring几乎是完美的设计、测试和锐化仪器,甚至可以用于企业应用程序服务器。@Transactional是管理事务的声明式方式,它比任何aop吐露都方便和可读性强。它的好处包括以声明方式自动处理所有事务管理方面:隔离和传播级别(不容易控制嵌套事务)、超时、回滚条件和服务类的每个方法的不同TransactionManagers。易于阅读,易于配置,易于使用。

代码语言:javascript
复制
@Transactional(readOnly = false, rollbackFor = ServiceException.class, isolation = Isolation.READ_COMMITTED)
public void myServiceJob(...)

当您看到此方法时,很容易理解它的事务属性(而不需要在方法中提供事务实现细节)。对于普通的AOP,每次您想知道在这个方法中发生了什么时,您都应该检查xml配置并找到相应的方法,这就不那么优雅了。

另一方面,很难在任何其他声明性管理中调试或使用这些代理。例如,从上下文中提取bean是很棘手的(但不是不可能的),并使用反射从包装好的bean中获取一些内容(例如,为了监视目的)。此外,当bean调用其方法之一时,它不会被委托给代理,因为您的bean不了解代理,因此this引用bean本身。唯一的方法是将其解锁以提供"self“字段,并在自定义bean后处理器中设置它(但您的实现也会受到这种影响)。

Implementation

如果Spring被配置为使用事务性管理,那么它将在bean的定义上寻找@Transactional注释,并创建自动生成的AOP代理,这是bean的子类。Spring代理的默认行为只是将方法的调用委托给底层bean。然后Spring向TransactionInterceptor注入必要的TransactionManagers。拦截器代码看起来非常简单:

代码语言:javascript
复制
public Object invoke(final MethodInvocation invocation) throws Throwable {
    // Work out the target class: may be {@code null}.
    // The TransactionAttributeSource should be passed the target class
    // as well as the method, which may be from an interface.
    Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);

    // Adapt to TransactionAspectSupport's invokeWithinTransaction...
    return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {
        @Override
        public Object proceedWithInvocation() throws Throwable {
            return invocation.proceed();
        }
    });
}

invokeWithinTransaction内部,TransactionInterceptor决定调用是在调用事务的范围内(如果存在)还是在新的事务中(这是关于传播级别的)。然后选择相应的TransactionManager,配置超时和隔离级别,然后调用该方法。在决定事务是否应该执行或回滚之后(根据捕获的异常和时间进行选择)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29239285

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档