@Transactional 仅用于一种方法

时间:2021-04-15 10:01:25

标签: java spring spring-boot transactions spring-transactions

我需要创建一个包含模式列表的 @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。 你有解决办法吗?

1 个答案:

答案 0 :(得分:0)

  • 您必须确保您对事务管理器进行了如下配置:
@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 为那些类创建了代理 在类本身或成员上声明 @Transactional。代理是 在运行时大多不可见。它为 Spring 提供了一种注入方式 方法调用之前、之后或周围的行为 代理。事务管理只是行为的一个例子 可以挂钩。安全检查是另一回事。你可以 也为日志记录之类的事情提供你自己的。所以当你注释一个 方法与@Transactional,Spring 动态创建一个代理 实现与您正在注释的类相同的接口。和 当客户端调用您的对象时,调用会被拦截 以及通过代理机制注入的行为。