@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(){...}
}
 

But at a very high level, Spring creates proxies for classes that declare @Transactional on the class itself or on members. The proxy is mostly invisible at runtime. It provides a way for Spring to inject behaviors before, after, or around method calls into the object being proxied. Transaction management is just one example of the behaviors that can be hooked in. Security checks are another. And you can provide your own, too, for things like logging. So when you annotate a method with @Transactional, Spring dynamically creates a proxy that implements the same interface(s) as the class you're annotating. And when clients make calls into your object, the calls are intercepted and the behaviors injected via the proxy mechanism.