How to fix connection close issue in synchronised method?

179 Views Asked by At

In our application, we are using grails framework and SQL server for database. We have multiple sites and those sites can have multiple users (a few users) and if they are accessing the same method via AJAX that can cause issue so we made the that method as synchronized method and to minimize the database interaction we are storing data in map on site basis since all the user from one site will get the same data, and if the data is older than 10 seconds we get the data from database and update the map object. Here we are getting a lot of database connection close issues on the very first line of synchronized method where we are getting site object from database. What is the issue here and how we can resolve the issue?

def synchronized getData(params){
  Site site = Site.get(params.siteId)
  // Here we are checking whether site data does not exists in map
  // or the data expired (10 second older data) then we get data from
  // database and update the map object

  // Then here we create new list object from the data in map object

  return list
}
1

There are 1 best solutions below

6
On

Difficult to figure out the exact problem without more information here. Several things stand out...

I'm not especially familiar with using the synchronized keyword in front of a service method, I would recommend trying the synchronized annotation with a static object key:

private static final myLock = new Object()

@Synchronized("myLock")
void getData() {
  //do stuff
}

or synchronizing explicitly within the method

void getData() {
  synchronized(myLock) {
    //do stuff
  }
}

I don't know if that's related to your connection closing issues, but worth a try.

But also notably, grails and hibernate provide caching of database retrieves, so if you're loading the same data that's been loaded into hibernate cache, you don't need to cache this in a Map locally... grails is already doing that for you. Site site = Site.get(params.siteId) will NOT make a database call if it's been called recently and is already cached by the framework.

I would strongly suggest running some performance checks just making that call vs. caching in a Map object, especially if you're expiring in ~10s anyway.