【问题标题】:Entities not persisted to DB when using Spring's asynchronous execution使用 Spring 的异步执行时实体未持久化到 DB
【发布时间】:2019-05-03 13:23:29
【问题描述】:

我需要运行一个异步作业,将数据(从文件中读取)导入 MySQL 数据库。我正在使用 Spring Data 的CrudRepository。问题是尽管调用了 save 方法,但没有数据被持久化到数据库中。

老实说,我不知道如何开始解决这个问题。我在我的日志中没有看到任何错误或警告,在 Google 上搜索我只发现了以下建议:

Spring JPA: Data not saved to Database when processing from an Async method

但是,我已经应用了它,但我的代码仍然无法正常工作。同步运行代码(通过删除@Async 注解),一切正常。

我的代码的 sn-p:

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> {
}

我希望将我的地址保存到数据库中,但是在运行作业后(并且没有收到任何错误或警告),数据库仍然是空的。

我已经盯着这个看了好几个小时了,欢迎所有的想法!

【问题讨论】:

    标签: java spring transactions spring-data


    【解决方案1】:

    在调用@Async 时,可能有一个事务已经在运行,因此异步方法会选择相同的事务上下文。

    另一方面,在异步方法完成之前,事务可能已由父代码提交。

    一般来说,建议使用新的/嵌套事务调用异步方法:

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void import() {
    

    感谢它不会依赖于父事务。

    更新

    您还保存了一个实体列表。尝试使用:

    addressRepository.saveAll(adresses);
    

    【讨论】:

    • 感谢您的意见!我把@Transactional注解改成了@Transactional(propagation = Propagation.REQUIRES_NEW),可惜没有解决我的问题。
    • 在 crud 存储库中没有 saveAll 方法(使用 spring-data-jpa 1.9.4),只有 save(Iterable&lt;S&gt; entities)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-28
    • 2012-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-06
    相关资源
    最近更新 更多