Multithreading 使用JpaRepository在指定时间后删除实体
我使用的是Spring Boot和H2 db。我有一个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
产品
实体,我希望我的应用程序能够从数据库中删除该产品,但我的要求是:首先将活动
标志设置为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());
}