What's the best practice to ensure atomic read of a database table using JDBC?

前端 未结 6 1298
情深已故
情深已故 2021-02-19 06:26

I have an java application reading from a database table for jobs to process, and I may have multiple instances of this application running on different servers as each job is i

6条回答
  •  青春惊慌失措
    2021-02-19 07:22

    Problem

    Take jobs ready to process and make their status running atomically.

    Solution

    No need for additional locks. Since an update operation is already atomic by itself in terms of the same query (see the excerpt from the docs below), update the jobs table, setting the status running to those that are ready to be processed and get the result of this update - it will be the jobs you took for processing.

    Examples:

    Postgres

    UPDATE jobs SET status = 'running'
      WHERE status is NULL
    RETURNING id;
    

    In terms of JDBC you can go similar to this:

    String sql = "update ... returning ...";
    boolean hasResult = statement.execute(sql);
    if (hasResult) {
        ResultSet rs = statement.getResult();
    }
    

    SQL Server

    UPDATE jobs SET status = 'running'
      WHERE status is NULL
    OUTPUT UPDATED.id;
    

    Excerpt from the Postgres documentation that shows how 2 transactions behave when doing UPDATE on the same table with the same query:

    UPDATE will only find target rows that were committed as of the command start time. However, such a target row might have already been updated (or deleted or locked) by another concurrent transaction by the time it is found. In this case, the would-be updater will wait for the first updating transaction to commit or roll back (if it is still in progress).

提交回复
热议问题