0

テーブルからデータを読み取り、各行で何らかの作業を行い、行を更新済みとしてマークする必要があります。更新された行を再度読み取りたくありません。これが、ExecutorService で行うことを計画していることです。これは正しいです ?

ありがとう。

public class ScheduledDBPoll
{
    public static void main(String args[])
    {
        ExecutorService service = Executors.newFixedThreadPool(10);
        /* Connect to database. */
        while (true)
        {
        /* Issue a select statment for un-updated rows. */
            /* Get the primary key. */

            service.submit(new Task(primaryKey));      /* Pass the primary key*/
            try
            {
                Thread.sleep(3000);     /* Sleep for 3 seconds. */
            }
            catch (InterruptedException ex)
            {
                Logger.getLogger(ScheduledDBPoll.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        /* Close the connection here. */
    }
}

final class Task implements Runnable
{
    private int taskId;

    public Task(int primayKey)
    {
        this.taskId = primayKey;
    }

    @Override
    public void run()
    {
        try
        {
            /* Connect to database. */
            /* Select the passed primary key row. */
            /* Do some work,  mark the row as updated. */
            /* Close the connection here. */            
        }
        catch (InterruptedException ex)
        {
            Logger.getLogger(Task.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

Firebird データベースを使用しています。Firebird は接続レベルでのみスレッドセーフです。そのため、同じ接続に対して異なるスレッドで 2 つのクエリが実行されるのを避けようとしています。また、上記のコードは Windows サービスとして実行されるため、新しく挿入されたレコードを常に探していることを忘れていました。

4

2 に答える 2

1

私は ScheduledExecutorService を使用し、3 秒ごとにジョブを送信するスレッドはありません。データベース接続の作成は非常に遅いため、接続を開いたままにします。

だから私はそれをもっと好きに実装します

ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
service.scheduleAtFixedRate(new Task(), 1, 1, TimeUnit.SECONDS);


final class Task implements Runnable {
    private Connection connection;
    private int taskId;

    @Override
    public void run() {
        try {
            if (!connectionIsOkay()) {
                connectToDatabase();
                taskId = selectUnUpdatedRow();
            }
            selectRowsToUpdate();
            processRowsToUpdate();
            markAsUpdated();

        } catch (Exception ex) {
            Logger.getLogger(Task.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    // TODO find a more elegant way to close the connection when finished.
    public void finalise() {
        closeConnection();
    }
}
于 2013-10-13T14:37:58.947 に答える
0

まず、重要な用語の問題です。このコードは「a」ワーカー スレッドを実装していません。最大 10 個のスレッドから同時データベース アクセスを試みます。

したがって、実際に 1 つのワーカー スレッドのみが必要な場合は、固定スレッド プールのサイズを 10 ではなく 1 にする必要があります

なぜあなたが 3 秒待っているのかわかりません (実際には、あなたのコメントが何を言っているかにかかわらず 1 秒です)、それは無意味に思えます。

それ以外は正しいようです。

于 2013-10-13T14:31:12.400 に答える