尝试在单个方法中选择并插入时出现多线程问题

时间:2019-01-25 09:45:49

标签: java playframework ebean

朋友! 我正在使用Play + Java + Ebean。 尝试以一种方法选择值并将其插入数据库时​​,并行线程出现问题。 首先,我通过id检查DB(PostgreSQL)中是否存在设备。 如果没有按ID查找设备,则尝试将其插入数据库。 然后我返回设备对象。 除了两个http请求异步尝试向我发送相同的设备ID的情况以外,其他所有方法都工作正常。首先,他们两个都从DB中选择一个值,并且什么也不返回。然后一个插入值,第二个由于io.eBean.DuplicateKeyException而失败。

我尝试同步方法。它可行,但我不喜欢这种解决方案。如果我这样做,许多请求将被排入队列。我想保持并行,但仅在我有两个或多个具有相同ID的请求时才进行同步。 解决该问题的另一种方法是使用INSERT ... WHERE NOT EXISTS(SELECT ...)RETURNING编写查询。但这不是对象样式,并且对相同类型的多个操作进行了硬编码。

public CompletionStage<Device> getDevice(String deviceID, String ipAddress) {
return CompletableFuture.supplyAsync(() -> 
SecurityRepository.findDeviceByDeviceID(deviceID))       
    .thenApplyAsync(curDevice -> curDevice
        .orElseGet(() -> {
            List<Device> devices = 
            SecurityRepository.listDevicesByIpAddress(ipAddress);
            if(devices.size() >= 10) {
                 for(Device device : devices)
        device.delete();
    }
    Device newDevice = new Device();
    newDevice.setDeviceID(deviceID);
    newDevice.ipAddress = ipAddress;
    newDevice.save(); //here is the problem
    return newDevice;
      })
);

}

仅当deviceID相同时,我才想同步此方法。 您对这个问题有什么建议吗? 谢谢。

0 个答案:

没有答案