gpt4 book ai didi

java - 在线程中删除时 TransactionRequiredException

转载 作者:行者123 更新时间:2023-12-02 10:12:00 28 4
gpt4 key购买 nike

当我尝试使用 Hibernate 的多线程从数据库中删除数据时遇到问题。

repo :

@Modifying
@Query("DELETE FROM Customer cus WHERE cus.customerId in :customerIds")
public void deleteByCustomerIds(@Param("customerIds") List<Long> customerIds);

服务:

public runDelete (List<Long> customerIds) {
List<List<Long>> partitions = Lists.partition(customerIds, 5000);

for(int i = 0; i < partitions.size(); i++ ) {
final int index = i;
Runnable thread = () -> deleteCustomersInBatches(partitions.get(index));
new Thread(thread).start();
}
}

@Transactional(propagation = Propagation.REQUIRES_NEW)
private void deleteCustomerInBatches(List<Long> customerIds) {

for (List<Long> batch : Lists.partition(oldCalcIds, 1000)) {
customerRepo.deleteByCustomerIds(batch);
}
}

这就是代码的样子,我在进行存储库调用的服务层上有 @Transactional 标记。

at java.lang.Thread.run(Thread.java:748) Caused by: javax.persistence.TransactionRequiredException: Executing an update/delete query at org.hibernate.jpa.spi.AbstractQueryImpl.executeUpdate(AbstractQueryImpl.java:54)

我不断收到此错误。任何帮助表示赞赏。

最佳答案

这是因为您从同一个 bean 中调用 @Transactional 方法。

@Transactional 仅适用于在 spring 创建的代理上调用的方法。这意味着,当您创建 @Service 或其他 bean 时,从外部调用的方法将是事务性的。如果从 bean 内部调用,则不会发生任何事情,因为它不通过代理对象。

最简单的解决方案是将方法移至另一个 bean。如果你真的想将它保留在同一个组件中,那么你需要调用它,以便它被 Spring AOP 包装在代理中。你可以这样做:

private YourClass self;

@Autowired
private ApplicationContext applicationContext;

@PostConstruct
public void postContruct(){
self = applicationContext.getBean(YourClass.class);
}

然后调用 self 上的方法将导致打开交易。

关于java - 在线程中删除时 TransactionRequiredException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54950278/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com