I've the next problem:

I've got a multithreaded server-side application, where every request executes a brand new thread (the conventional situation). According to this request, the applying inspections when the data needed is cached within the DB already. If so, it brings it and transmits it to the customer. Otherwise, an online services are known as the fact is saved within the DB after which fetched to become came back towards the client.

The service requires a while to calculate the information, because the demands to my application are performed asynchronously, I fall under the trap of 1 request checking the DB, simply because there's nothing there, then calling the service. Meanwhile however, another request with similar input would look into the DB, because the service requires a while, there still could be nothing there ... therefore it would initiate another call towards the service. Consequently, the information will get written to DB two times, which screws up any successing procedures, depending on its originality (there can not be two records with similar data)

What solution must i choose? One idea is always to put specific UNIQUE area constraints within the DB. By doing this, even when the application attempts to write two times, the DB only will reject it, and also the application will throw the best. However, the service it's still performed multiple occasions.

Another solution that found my thoughts is always to synchronize the technique, which calls the net service. By doing this, every successive request to my application is going to be placed on a waiting stack prior to the previous operation is completed. By doing this, if another request with similar input data is available in, while the first continues to be awaiting the outcomes in the remote service, it'll sit and wait for a operation to become finished. Then, because the second request inspections the DB, the information will be there, and there won't be any have to call the serivice again. This can also prevent from getting multiple identical records within the DB. The issue with this particular would be that the speed of my server application will disappear inevitably, because EVERY request will need to wait, the ones which normally should not (those, that allegedly finances data within the DB)

Every other suggestions? I'm stuck. How do i implement some kind of conditional synchronization?

Just implement this formula:

  • get data in the DB
  • if data is available, return data
  • if data does not exist, obtain a lock connected using the id from the data to obtain // obstructing call
  • after you have the lock, see if data is incorporated in the DB, and when so, return the information. Else, call the service and set the information within the DB
  • release the lock

By doing this, waiting on the lock only if the information does not appear in the DB yet. The very first concurrent thread obtaining the lock is the only person calling the service, and the rest of the ones obtain the data in the DB.

This should not stop you from properly creating the database, and taking advantage of a distinctive primary key for that data. It it's still needed for those who have a cluster of servers anyway.

You can just synchronize the calculation part, i.e. use double checked securing:

boolean dataExists = checkDB();
if( !dataExists ) {
  synchronized( someSharedObject ) {
    //another thread might have been waiting too and now has put the data into the DB
    //thus check again
    if( !checkDB() ) {
      calculateDataAndWriteToDB();
    }  
  }
}
//do whatever you want with the existing data

Use situation that you simply referred to appears like typical caching use situation. As well as in caches data normally has some key and cost where key defines originality . If other request updates the information it won't create new record but update existing one with similar key. Should you choose it by doing this the cost you have to pay is simply calling the service two times but it shouldn't modify the logic. So it is possible to reason you create new record each time rather than upgrading?

And That I highly advise against using any method synchronization inside your use situation because it instantly makes your solution not scalable over multiple boxes.