Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring事务管理:使用@Transactional与使用AOP(_Java_Spring_Aop_Spring Transactions - Fatal编程技术网

Java Spring事务管理:使用@Transactional与使用AOP(

Java Spring事务管理:使用@Transactional与使用AOP(,java,spring,aop,spring-transactions,Java,Spring,Aop,Spring Transactions,我对Spring事务管理感到困惑。在我的应用程序中,我在服务类中使用@Transactional实现了事务管理。我将我的spring.xml配置为: <beans:bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <beans:property name="dataSource" ref="dataSource"

我对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也是AOP在春季的实现。谁能告诉我怎么做吗?

不会的

利益

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

@Transactional(readOnly = false, rollbackFor = ServiceException.class, isolation = Isolation.READ_COMMITTED)
public void myServiceJob(...)
当您看到这个方法时,很容易理解它的事务属性,而无需在方法中提供事务实现细节。对于普通AOP,每当您想知道这个方法中发生了什么时,您应该检查您的xml配置并找到相应的方法,这样就不那么优雅了

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

实施

如果Spring被配置为使用事务管理,它将在bean的定义上寻找@transactional注释,并创建自动生成的AOP代理,它是bean的子类。Spring代理的默认行为只是将方法调用委托给底层bean。然后Spring向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,配置超时和隔离级别,然后调用该方法。在决定是否提交或回滚事务后,将根据捕获的异常和时间进行选择。

感谢您的回答。你不仅回答了我的问题,还让我了解了spring事务。我觉得@Transactional更容易理解和工作。当Spring管理整个事务过程时,现在我可以选择这种方法而不是基于xml的事务管理方法。