我需要运行一个异步作业,该作业将数据(从文件读取)导入到MySQL DB。我正在使用Spring Data的CrudRepository
。问题是,尽管调用了save方法,但是没有数据持久保存到数据库中。
老实说,我不知道如何开始解决这个问题。我在日志中没有看到任何错误或警告,并且在Google上搜索时,我仅发现以下建议:
Spring JPA: Data not saved to Database when processing from an Async method
但是,我已经应用了它,但是我的代码仍然无法正常工作。同步运行代码(通过删除@Async
批注),一切都会按预期进行。
我的代码段:
AsyncImportService.java
@Service
public class AsyncImportService {
@Autowired
private ImportService importService;
@Async
public void import() {
importService.import();
}
}
ImportService.java
@Service
public class ImportService {
@Autowired
private AddressCrudRepository addressRepository;
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void import() {
List<Adres> adresses = new ArrayList<>();
// Open file and create buffered reader using try-with-resources
try (BufferedReader reader = ...) {
while((line = reader.readLine()) != null) {
// mapAddress converts a line of text to an Address object
addresses.add(mapAddress(line));
}
addressRepository.save(adresses);
} catch (IOException e) {
// Handle exception
}
}
}
AdresCrudRepository.java
public interface AddressCrudRepository extends CrudRepository<Address, Long> {
}
我希望将地址保存到数据库中,但是在运行作业(并且没有收到任何错误或警告)之后,数据库仍为空。
我已经盯着看了好几个小时了,所有想法都欢迎!
答案 0 :(得分:0)
在调用@Async
时可能已经有一个事务在运行,因此异步方法选择了相同的事务上下文。
另一面是,异步方法完成之前,事务可能已经由父代码提交了。
通常,建议使用新的/嵌套事务调用异步方法:
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void import() {
由于它不会依赖于父事务。
更新
您还要保存一个实体列表。尝试使用:
addressRepository.saveAll(adresses);