繁体   English   中英

@Transactional 仅在一种方法上

[英]@Transactional only on one method

我需要创建一个具有模式列表的@Scheduled 方法,并且对于每个模式,从 2 个表中删除行。

    @Scheduled(fixedDelay = 10000)
public void scheduleFixedDelayTask() {
    List<String> presentSchemas = getPresentSchemas();
    for (String schema : presentSchemas) {
        deleteFromCustomerTables(schema);
    }
}

我已将 deleteFromCustomerTables 定义为 @Transactional(propagation = Propagation.REQUIRES_NEW) 并在其中使用 EntityManager 从 2 个表中删除行。

为了使其工作,我需要将@Transactional 添加到 scheduleFixedDelayTask,否则我会收到 TransactionRequiredException。

我的问题是我不希望整个调度程序成为@Transactional,如果一个模式出现问题,我不想回滚所有模式。

我也尝试过不使用 @Transactional 并使用:

    Session session = entityManager.unwrap(Session.class);
    Transaction t = session.beginTransaction();
    //exec delete
    t.commit();
    session.close();

但我仍然收到 TransactionRequiredException。 你有解决方案吗?

  • 您必须确保您配置了事务管理器,如下所示:
@Configuration
@EnableTransactionManagement
public class TransactionConfig {

  @Bean
  @Primary
  public PlatformTransactionManager transactionManager() {
    return new JpaTransactionManager();
  }
}
  • 您必须确保方法 deleteFromCustomerTables 不在同一个组件中,如下所示:
@Component
class Component1 {
   void scheduleFixedDelayTask(){...}
}

@Component
class Component2 {
   void deleteFromCustomerTables(){...}
}
 

但在非常高的级别上,Spring 为在 class 本身或成员上声明 @Transactional 的类创建代理。 代理在运行时大部分是不可见的。 它为 Spring 提供了一种在方法调用之前、之后或周围将行为注入被代理的 object 的方法。 事务管理只是可以挂钩的行为的一个例子。安全检查是另一个例子。 你也可以提供你自己的,比如日志记录。 因此,当您使用 @Transactional 注释方法时,Spring 会动态创建一个代理,该代理实现与您正在注释的 class 相同的接口。 当客户端调用您的 object 时,调用会被拦截并通过代理机制注入行为。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM