【问题标题】:Why does not "@Transactional(propagation = propagation.NEVER)" work?为什么“@Transactional(propagation = propagation.NEVER)”不起作用?
【发布时间】:2015-04-24 21:02:44
【问题描述】:

在 Spring 文档中,对于 NEVER 传播:

非事务性执行,如果有事务则抛出异常 存在。

我想尝试如下:

@Transactional(propagation = Propagation.NEVER)
public void getDeps(long ID) {
    System.out.println(databaseImp.getDepartmentByID(ID));
}

@Transactional(propagation = Propagation.REQUIRED)
public void allProcessOnDB_second(long ID) {
    getDeps(ID);
    operation(ID);
}

@Transactional
public void operation(long id){
    System.out.println(databaseImp.getDepartmentByID(id));
}

好吧,代码想要做什么并不重要。
我使用@Transactional(propagation = Propagation.NEVER) 并在任何事务 方法中使用此方法,但它不起作用。我的意思是它必须抛出异常,但它不会。

我的 Spring 元配置文件 (XML) 包含以下内容:

<context:annotation-config></context:annotation-config>
<context:component-scan base-package="database.transactionmanagement"/>

<tx:annotation-driven transaction-manager="transactionManager" mode="aspectj"/>

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <constructor-arg name="dataSource" ref="datasource2"/>
</bean>

<bean id="datasource2" class="org.apache.tomcat.dbcp.dbcp2.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost/hr"/>
    <property name="username" value="root"/>
    <property name="password" value=""/>
</bean>

感谢您的回答。

【问题讨论】:

    标签: java spring transactions spring-aop spring-annotations


    【解决方案1】:

    @Transactional 注解仅适用于 Spring 代理对象。例如,如果您从某个注入您的服务的 Spring bean 调用 allProcessOnDB_second()

    @Autowired 
    private MyService myService; 
    ...
    myService.allProcessOnDB_second();
    

    那么myService是Spring代理,它的@Transactional(propagation = Propagation.REQUIRED)被应用。如果您要调用myService.getDeps(id),则将应用@Transactional(propagation = Propagation.NEVER)

    但是当你调用第一个方法,然后调用第二个方法时,第二个方法不是通过Spring代理调用而是直接调用,所以它的事务配置被忽略了。

    【讨论】:

    • 是的@Predrag Maric,我试着照你说的做,效果很好,我有一个问题,我们可以说,如果我们使用事务注释,我们需要使用必要的代理类并调用这个或这些类中的事务方法。
    • 您只需要了解它是如何工作的,然后您就可以按预期使用它。这里最重要的是理解 Spring 代理的概念。
    【解决方案2】:

    Spring 事务是基于代理的。如果 bean A 调用另一个 bean B,则会抛出该异常,因为事务方面会拦截调用并抛出异常。但是在这里,您在同一个对象中调用了另一个方法,因此事务代理不适用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-14
      • 1970-01-01
      • 1970-01-01
      • 2013-03-23
      • 1970-01-01
      • 1970-01-01
      • 2019-01-07
      • 2020-06-12
      相关资源
      最近更新 更多