0

I have a Java web application, running in a cluster of Tomcat application servers and a shared SQL/JDBC database. Data from the database is cached in memory in each instance of the web app.

My web application needs to update the database periodically with weather report data from a source outside of my web application (i.e. a background thread periodically collects and writes a whole bunch of data rows into a table in the database using SQL). Only one instance of my web application in the cluster should do this and then make the other instances aware that the data in the database has changed so that they can flush their caches and start using the updated data from the database. The propagation of the update to the database doesn't need to be real time.

What is the best practice to achieve this? How do I negotiate, which node will be the one to perform the updates? Which JEE technologies could I use? I want to avoid simply polling for changes in the database.

  • 1
    Polling is a perfectly good solution, unless you need database changes to propagate in real-time (say, less than an hour). Or, you can simply implement a push mechanism. Can you be more specific about your requirements? As your question is currently written, there really isn't enough information to make it meaningfully answerable. – Robert Harvey Nov 25 '14 at 18:05
  • OK, so I will use polling for changes in the database, but how do I negotiate a node to do the updates? – Twilite Nov 25 '14 at 18:27
  • Not a duplicate @KilianFoth, since I don't want to handle concurrent updates to the database but propagate updates in a clustered setting. – Twilite Nov 25 '14 at 18:33
  • 1
    How are you caching the database in a node currently? – user40980 Nov 25 '14 at 19:27
  • In a simple data structure @MichaelT (Java Map Object) – Twilite Nov 26 '14 at 10:27
1

Using a messaging broker seems like the best tool to inform other applications that they should update rather than polling (which is fine really too).

http://www.rabbitmq.com/

Locking the database table for writing is what you want to prevent race conditions.

2

We have a cluster-environment too. We use Hazelcast for such jobs. With Hazelcast you could embed the codeblock for updating within a "Hazelcast-Lock-Section". It is not my favourite solution, but this is how it is done in our application (and maybe suits hazelcast your needs).

I opt for a smaller and easier solution: I would write a small (buzzword-alarm: micro-) service using Spring Boot.

Its only job is to update the data. It does not interfere with your application. And when it has finished its job, it could notify the application (if necessary). And the best part: you need no negotiation between instances.

The advantages of a small service are:

  • separation of concerns. A separate service which does only one thing (and does that well).

  • runs independent of other parts of the application.

  • errors are obviously limited to this service

  • easy to (un-)deploy

Advantages of Spring Boot:

Other frameworks, which might be interesting for such a task are Dropwizard or Vert.x. I tried neither, but maybe you take a look.

P.S.:

Data from the database is cached in memory in each instance of the web app

Don't do that. There are nicer solutions like memcached or redis

Not the answer you're looking for? Browse other questions tagged or ask your own question.