Dropwizard:线程安全同步块,用于插入和更新

时间:2018-06-06 23:41:33

标签: java thread-safety dropwizard

我不确定这是否正确处理,但我有以下方法:

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();
    }
}

这确实解决了这个问题,但这对我来说似乎不具备可扩展性。有没有更好的方法来处理这样的情况?什么促进可扩展性?或者这是处理情况的首选/推荐方法。该服务是使用Postgresql的JDBC连接的Dropwizard(0.9.2)服务。任何帮助或见解将是最受欢迎的。谢谢!

更新:我尝试在事务中使用jdbi方法但仍然存在多线程问题。代码如下

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;
    })
}

0 个答案:

没有答案