4

I'm using JDBC, need to constantly check the database against changing values.

What I have currently is an infinite loop running, inner loop iterating over a changing values, and each iteration checking against the database.

public void runInBG() { //this method called from another thread
    while(true) {
     while(els.hasElements()) {
      Test el = (Test)els.next();
       String sql = "SELECT * FROM Test WHERE id = '" + el.getId() + "'";
       Record r = db.getTestRecord(sql);//this function makes connection, executeQuery etc...and return Record object with values
       if(r != null) {
         //do something
       }
     }
    }
}

I'm think this isn't the best way.

The other way I'm thinking is the reverse, to keep iterating over the database.

UPDATE

Thank you for the feedback regarding timers, but I don't think it will solve my problem. Once a change occurs in the database I need to process the results almost instantaneously against the changing values ("els" from the example code).

Even if the database does not change it still has to check constantly against the changing values.

UPDATE 2

OK, to anyone interested in the answer I believe I have the solution now. Basically the solution is NOT to use the database for this. Load in, update, add, etc... only whats needed from the database to memory. That way you don't have to open and close the database constantly, you only deal with the database when you make a change to it, and reflect those changes back into memory and only deal with whatever is in memory at the time. Sure this is more memory intensive but performance is absolute key here.

As to the periodic "timer" answers, I'm sorry but this is not right at all. Nobody has responded with a reason how the use of timers would solve this particular situation.

But thank you again for the feedback, it was still helpful nevertheless.

Thomas Mueller
  • 48,905
  • 14
  • 116
  • 132

6 Answers6

3

Another possibility would be using ScheduledThreadPoolExecutor.

You could implement a Runnable containing your logic and register it to the ScheduledExecutorService as follows:

ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(10);
executor.scheduleAtFixedRate(myRunnable, 0, 5, TimeUnit.SECONDS);

The code above, creates a ScheduledThreadPoolExecutor with 10 Threads in its pool, and would have a Runnable registered to it that will run in a 5 seconds period starting immediately.


To schedule your runnable you could use:

scheduleAtFixedRate

Creates and executes a periodic action that becomes enabled first after the given initial delay, and subsequently with the given period; that is executions will commence after initialDelay then initialDelay+period, then initialDelay + 2 * period, and so on.

scheduleWithFixedDelay

Creates and executes a periodic action that becomes enabled first after the given initial delay, and subsequently with the given delay between the termination of one execution and the commencement of the next.


And here you can see the advantages of ThreadPoolExecutor, in order to see if it fits to your requirements. I advise this question: Java Timer vs ExecutorService? too in order to make a good decision.

Community
  • 1
  • 1
Francisco Spaeth
  • 23,493
  • 7
  • 67
  • 106
1

Keeping the while(true) in the runInBG() is a bad idea. You better remove that. Instead you can have a Scheduler/Timer(use Timer & TimerTask) which would call the runInBG() periodically and check for the updates in the DB.

Rahul
  • 44,383
  • 11
  • 84
  • 103
  • You can skip the `Timer` and `TimerTask` codification by using a framework that handles scheduled operations like [quartz](http://quartz-scheduler.org/) – Luiggi Mendoza May 14 '13 at 05:51
  • Agreed scheduling using scheduler is the way to go, but since, OP hasn't mentioned anything about using third party libs, using standard java classes seems to be a good option! Scheduling can be implemented later on, if the OP is fine with 3p libs! – Rahul May 14 '13 at 05:54
  • FYI, I am myself a Quartz user! :) – Rahul May 14 '13 at 05:55
  • 1
    Just adding the info in case configuring `Timer` manually would give a headache since frameworks like this one already handle lot of problems. And yes, I'm a quartz user to (disclaimer: I'm not related with the library development nor with any customer support, just a happy user of it). – Luiggi Mendoza May 14 '13 at 05:56
  • this has to be constant checking as when any change in database happens in that very moment the results must be processed. I don't see how using a timer can solve that. –  May 14 '13 at 06:13
  • regardless of whether the database changes or not, the checking must go on with no stops. –  May 14 '13 at 06:28
1

u could use a timer--->

Timer timer = new Timer("runInBG");

    //Taking an instance of class contains your repeated method.
    MyClass t = new MyClass();

    timer.schedule(t, 0, 2000);
Ashok Damani
  • 3,896
  • 4
  • 30
  • 48
0

As you said in the comment above, if application controls the updates and inserts then you can create a framework which notifies for 'BG' thread or process about change in database. Notification can be over network via JMS or intra VM using observer pattern or both local and remote notifications.

You can have generic notification message like (it can be class for local notification or text message for remote notifications)

<Notification> 
  <Type>update/insert</Type>
  <Entity>
     <Name>Account/Customer</Name>
     <Id>id</Id>
  <Entity> 
</Notification>
Peeyush
  • 422
  • 3
  • 13
0

To avoid a 'busy loop', I would try to use triggers. H2 also supports a DatabaseEventListener API, that way you wouldn't have to create a trigger for each table.

This may not always work, for example if you use a remote connection.

Thomas Mueller
  • 48,905
  • 14
  • 116
  • 132
0

UPDATE 2

OK, to anyone interested in the answer I believe I have the solution now. Basically the solution is NOT to use the database for this. Load in, update, add, etc... only whats needed from the database to memory. That way you don't have to open and close the database constantly, you only deal with the database when you make a change to it, and reflect those changes back into memory and only deal with whatever is in memory at the time. Sure this is more memory intensive but performance is absolute key here.