gpt4 book ai didi

java - Spring事务管理: using @Transactional vs using AOP (
转载 作者:太空宇宙 更新时间:2023-11-04 14:01:50 29 4
gpt4 key购买 nike

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

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

如果我在配置文件中实现事务管理,如下所示,而不在服务类中使用@Transactional:

    <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 相比,它能给我带来什么好处吗?有人告诉我使用@Transactional也是Spring AOP的实现。谁能解释一下怎么做?

最佳答案

不会的。

好处

如果您不需要一些非常具体的要求或者您没有性能问题,那么您不应该重新发明轮子。 Spring是一个近乎完美的设计、测试和磨砺的工具,甚至可以替代企业应用服务器。 @Transactional 是管理事务的声明式方式,它比任何 aop xml 配置更加方便和可读。它的好处包括以声明方式自动处理所有事务管理方面:隔离和传播级别(控制嵌套事务并不容易)、超时、回滚条件以及服务类的每个方法的不同 TransactionManager。易于阅读、易于配置、易于使用。

@Transactional(readOnly = false, rollbackFor = ServiceException.class, isolation = Isolation.READ_COMMITTED)
public void myServiceJob(...)

当你看到这个方法时,很容易理解它的事务属性(无需在方法中提供事务实现细节)。如果是普通的AOP,每次你想知道这个方法发生了什么,你应该检查你的xml配置并找到相应的方法,这样就不太优雅了。

另一方面,调试或使用这些代理进行任何其他声明性管理非常困难。例如。从上下文中提取 bean 并使用反射从包装的 bean 中获取某些内容(比如说,出于监视目的)是很棘手的(但并非不可能)。另外,当bean调用它的某个方法时,它不会被委托(delegate)给proxy,因为你的bean对proxy一无所知,所以this指的是bean本身。解决这个问题的唯一方法是提供“self”字段并将其设置在自定义 bean 后处理器中(但您的实现也会受到此影响)。

实现

如果 Spring 配置为使用事务管理,它会在 bean 定义上查找 @Transactional 注释并创建自动生成的 AOP 代理,该代理是 bean 的子类。 Spring代理的默认行为只是将方法的调用委托(delegate)给底层bean。然后 Spring 注入(inject) TransactionInterceptor 和必要的 TransactionManager。拦截器的代码看起来很简单:

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,配置超时和隔离级别,然后调用该方法。在决定是否应该提交或回滚事务之后(根据捕获的异常和时间进行选择)。

关于java - Spring事务管理: using @Transactional vs using AOP (<aop:advisor),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29239285/

29 4 0

Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com