Dropwizard: потокобезопасный синхронизированный блок для вставки и обновления - PullRequest
0 голосов
/ 07 июня 2018

Я не уверен, правильно ли это обрабатывать, но у меня есть следующий метод ниже:

public void updateOrInsertRecord () {
    boolean doesRecordExist = dao.doesUsageRecordExits();

    if (doesRecordExist) {
       dao.updateRecord();
    } 
    else {
       dao.insertRecord();
    }
}

Вышеуказанное может вызвать проблемы, если два потока заканчивают определять, существует ли запись,метод может потенциально вставить или обновить одну и ту же запись дважды.Было предложено поместить тело метода в синхронный блок, как показано ниже:

synchronized(this) {
    boolean doesRecordExist = dao.doesUsageRecordExits();

    if (doesRecordExist) {
       dao.updateRecord();
    } 
    else {
       dao.insertRecord();
    }
}

Это решает проблему, но для меня это не кажется масштабируемым.Есть ли лучший способ справиться с такой ситуацией?Что-то, что способствует масштабируемости?Или это предпочтительный / рекомендуемый метод обработки ситуации как таковой.Служба является службой Dropwizard (0.9.2), использующей соединение JDBC для Postgresql.Любая помощь или понимание будут наиболее ценными.Спасибо!

ОБНОВЛЕНИЕ: Я пытался использовать метод jTbi inTransaction, но проблема с многопоточностью сохраняется.Код ниже

public interface Dao extends Transactional<Dao> {

    @SqlQuery("SELECT EXISTS(SELECT STUFF)")
    Boolean doesRecordExists();

    @SqlCall("INSERT STUFF")
    void insertRecord();

    @SqlUpdate("UPDATE STUFF")
    void updateRecord();
 }

public void updateOrInsertRecord () {
    dao.inTransaction((transactional, status) -> {

         boolean doesRecordExist = dao.doesRecordExits();

        if (doesRecordExist) {
           dao.updateRecord();
        } 
        else {
           dao.insertRecord();
        }

        return null;
    })
}
...