Spring 尝试插入现有行的引导 JPA save() 方法

Spring Boot JPA save() method trying to insert exisiting row

我有一个简单的 kafka 消费者,它收集事件并根据其中的数据插入或更新数据库中的记录 - table 在 ID 列和实体字段中都有唯一的 ID 约束。

当 table 被预填充并且不时插入时,一切正常。然而,当我 t运行cate table 并发送几千个 ID 数量有限的事件(我在 3k 个事件中执行 50 个唯一 ID)时,事件会同时处理并且 save() 方法随机失败具有违反唯一约束的异常。我调试了一下,结果很简单。

event1={id = 1 ... //somedata} 被拾取,服务方法 saveOrUpdateRecord() 通过 ID=1 查找记录,找到 none, 插入一条新记录。

event2={id = 1 ... //somedata} 几乎同时被拾取,服务方法 saveOrUpdateRecord() 通过 ID=1 查找记录,找到 none(前一个是中间插入),尝试插入并因违反约束异常而失败 - 应该找到此记录并将其与基于我的条件的事件的输入合并。

我怎样才能让 saveOrUpdateRecord() 到 运行 仅当前一个完全执行以防止此类行为?我真的不想通过轮询大小等来减慢 kafka 消费者的速度,我只想让我的服务一次执行一个事务。

服务方式:

    public void saveOrUpdateRecord(Object input) {
    Object output = repository.findById(input.getId));

    if (output == null) {
        repository.save(input);

    } else {
        mergeRecord(input, output);
        repository.save(output);

    }
}

方法上的 @Transactional 注释会完成这项工作吗?

确保您的服务线程安全。 使用这个:

    public synchronized void saveOrUpdateRecord(Object input) {
    Object output = repository.findById(input.getId));

    if (output == null) {
        repository.save(input);

    } else {
        mergeRecord(input, output);
        repository.save(output);

    }
}