1

Here is my scenario: Each minute one thread checks database looking for some items. When items are found, they are passed to the another thread(consumer).

I use spring in my application, but it doesn't meant that I must use spring's classes, right? So, now I'm totally lost in the woods of ScheduledExecutorService (java), ExecutorService (java), TaskExecutor (spring), TaskScheduler (spring), @Scheduled (spring).

Help me please to understand what is the right way to implement my scenario.

serhii
  • 1,135
  • 2
  • 12
  • 29

2 Answers2

1

If I understand your question, you are using a Shared Database Pattern which, for for many reason is somewhat discouraged and used as a last resource.

If you want multiple application to communicate, and be decoupled, you should use Messaging ( eg: Spring Cloud Stream ).

Anyway, if you need to have a Shared Database, you may want what Listen / Notify provide.

From https://jdbc.postgresql.org/documentation/81/listennotify.html:

import java.sql.*;

public class NotificationTest {

    public static void main(String args[]) throws Exception {
        Class.forName("org.postgresql.Driver");
        String url = "jdbc:postgresql://localhost:5432/test";

        // Create two distinct connections, one for the notifier
        // and another for the listener to show the communication
        // works across connections although this example would
        // work fine with just one connection.
        Connection lConn = DriverManager.getConnection(url,"test","");
        Connection nConn = DriverManager.getConnection(url,"test","");

        // Create two threads, one to issue notifications and
        // the other to receive them.
        Listener listener = new Listener(lConn);
        Notifier notifier = new Notifier(nConn);
        listener.start();
        notifier.start();
    }

}

Listener

class Listener extends Thread {

    private Connection conn;
    private org.postgresql.PGConnection pgconn;

    Listener(Connection conn) throws SQLException {
        this.conn = conn;
        this.pgconn = (org.postgresql.PGConnection)conn;
        Statement stmt = conn.createStatement();
        stmt.execute("LISTEN mymessage");
        stmt.close();
    }

    public void run() {
        while (true) {
            try {
                // issue a dummy query to contact the backend
                // and receive any pending notifications.
                Statement stmt = conn.createStatement();
                ResultSet rs = stmt.executeQuery("SELECT 1");
                rs.close();
                stmt.close();

                org.postgresql.PGNotification notifications[] = pgconn.getNotifications();
                if (notifications != null) {
                    for (int i=0; i<notifications.length; i++) {
                        System.out.println("Got notification: " + notifications[i].getName());
                    }
                }

                // wait a while before checking again for new
                // notifications
                Thread.sleep(500);
            } catch (SQLException sqle) {
                sqle.printStackTrace();
            } catch (InterruptedException ie) {
                ie.printStackTrace();
            }
        }
    }

}

Notifier

class Notifier extends Thread {

    private Connection conn;

    public Notifier(Connection conn) {
        this.conn = conn;
    }

    public void run() {
        while (true) {
            try {
                Statement stmt = conn.createStatement();
                stmt.execute("NOTIFY mymessage");
                stmt.close();
                Thread.sleep(2000);
            } catch (SQLException sqle) {
                sqle.printStackTrace();
            } catch (InterruptedException ie) {
                ie.printStackTrace();
            }
        }
    }

}
Community
  • 1
  • 1
snovelli
  • 5,804
  • 2
  • 37
  • 50
0

Instead of using ScheduledExecutorService you can user quartz scheduler that is used to schdule some jobs in specific intervals, in your case every minute. It can be easily integrated with spring. Cron expressions are used to specify the time when to schedule. You can write your logic that checks database looking for some items in a class that extends QuartzJobBean class. See: https://examples.javacodegeeks.com/enterprise-java/quartz/spring-quartz-scheduler-example/