0

Will my Spring Rest Controller using a @Service class via @Autowired and @Service class having a critical section - synchronized on an instance field

private final Object modifyIndexLock = new Object(); be ready for distributed deployment or I need to synchronize in some other way?

Underlying resource being a Lucene Index Writer and at any point of time, only one writer can be opened. A thread trying to open a writer while its already open will fail. I don't want my thread to fail but wait.

Code works OK for a single server app deployment but I guess , it will fail in distributed environments since there will be multiple instances of @Service in each JVM resulting in different locks while underlying protected resource being a single one.

synchronized(modifyIndexLock){
//Open & use writer the close 
}

A pool of writers are not available but only a single instance.

IndexWriter

James Z
  • 12,209
  • 10
  • 24
  • 44
Sabir Khan
  • 9,826
  • 7
  • 45
  • 98

2 Answers2

1

If you have a distributed application, then each instance using its own lock, definitely won't guarantee exclusive access on a shared resource. You need to use a distributed lock (for example using Zookeeper) or you could also use a relational database to provide the lock that you need. see for example: https://www.xaprb.com/blog/2006/07/26/how-to-coordinate-distributed-work-with-mysqls-get_lock/

Jose Zevallos
  • 685
  • 4
  • 3
  • Thanks for giving the idea about using DB for lock & zookeeper. Its recommended [here](https://stackoverflow.com/questions/1059580/distributed-lock-service). For the time being, I am considering to keep a flag at DB since that seems simpler solution. – Sabir Khan Jun 13 '17 at 03:50
1

synchronized keyword is per JVM process. You can look into EJB spec with @javax.ejb.Singleton annotation which can provide locking across a distributed enterprise deployment. Look here for more info: https://docs.oracle.com/cd/E19798-01/821-1841/gipsz/index.html

Lev Kuznetsov
  • 3,520
  • 5
  • 20
  • 33