Multithreading 使用JpaRepository在指定时间后删除实体

Multithreading 使用JpaRepository在指定时间后删除实体,multithreading,spring-boot,spring-data-jpa,delete-row,Multithreading,Spring Boot,Spring Data Jpa,Delete Row,我使用的是Spring Boot和H2 db。我有一个产品实体,我希望我的应用程序能够从数据库中删除该产品,但我的要求是:首先将活动标志设置为false(然后在获取过程中不考虑此行),在特定时间段后从数据库中完全删除该行 @Entity @Table(name = "products") public class Product { @Id @GeneratedValue(generator = "inc") @GenericGen

我使用的是Spring Boot和H2 db。我有一个
产品
实体,我希望我的应用程序能够从数据库中删除该产品,但我的要求是:首先将
活动
标志设置为false(然后在获取过程中不考虑此行),在特定时间段后从数据库中完全删除该行

@Entity
@Table(name = "products")
public class Product {
    @Id
    @GeneratedValue(generator = "inc")
    @GenericGenerator(name = "inc", strategy = "increment")
    private int id;
    private boolean active = true;
    // getters & setters
}
服务层负责将
active
标志设置为false,并在稍后完成删除的方法(我没有任何东西可以完成我的要求的第二部分-在特定时间段后完成删除)

编辑

好的,我解决了我的问题:

@Transactional
public void deleteProduct(int id) {
    var target = repository.findProductByIdAndActiveTrue(id)
            .orElseThrow(() -> new IllegalArgumentException("No product with gicen id"));
    target.setActive(false);
    // complete removal after 150 seconds
    new Thread(() -> {
        try {
            Thread.sleep(150000);
            repository.deleteById(id);
        } catch (Exception e) {
            logger.error("Error removing the product");
        }
    }).start();
}

但是现在我的问题是,这是否是一个安全的解决方案,因为用户现在可能会启动太多线程,所以我认为有更好的解决方案来解决我的问题(在多线程方面更安全)

我不是专家,但我认为您试图实现的是一个糟糕的做法

我认为你应该做一个运动,例如每天做一次。 您应该在db中更新active的值。设置每次检查条目的计划,如果条目的活动值为false,则删除。大概是这样的:

public void deleteProduct(int id) {
    
    //update value to false
    repository.updateProductValue(id,false);
}
以及您的日程安排方法:

@Scheduled(fixedRate = 150000)
public void deleteNonActiveProducts() {

        List<Product> products = repository.findAllByFalseValue();
        products.forEach(product -> repository.deleteById(product.getId());
}
@计划(固定利率=150000)
public void deleteNonActiveProducts(){
List products=repository.findAllByFalseValue();
products.forEach(product->repository.deleteById(product.getId());
}
有了这个,你要做的就是每150000毫秒重复一次这个任务,这个任务的每次执行都是独立的和非并行的


希望对您很有用。

单击您的链接后,我得到404状态:/I可能是错误的,但我认为我的任务可以并行运行(每个删除任务都在一个单独的线程上运行)。但是,根据这一点,您的解决方案不能并行运行。如果您愿意,可以使其并行运行(您发布的链接也说明了这一点)但这不是重点。我可以问你为什么要延迟吗?我能想到的唯一合乎逻辑的解释是,你要等待另一个线程完成。如果是这种情况,你必须采取不同的方法来管理线程,这不是一项容易的任务。
@Scheduled(fixedRate = 150000)
public void deleteNonActiveProducts() {

        List<Product> products = repository.findAllByFalseValue();
        products.forEach(product -> repository.deleteById(product.getId());
}