有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

这确实解决了问题,但在我看来,这似乎不可扩展。有没有更好的方法来处理这种情况?促进可伸缩性的东西?或者这是处理此类情况的首选/推荐方法。该服务是一个Dropwizard(0.9.2)服务,使用Postgresql的JDBC连接。任何帮助或见解都将不胜感激。谢谢!

更新:我尝试使用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) 个答案