Reputation: 294
I have a synchronized method that is being called from a controller method. When two request access this only one should go through and other should be blocked until first is finished.
But when the incoming requests are fast, this is actually returning same accountId to two different requests, which is not intended.
Please help me understand how do I synchronize this getNextAccount() call so that it only return one account to one request.
Method in AccService.java
private final Object lockObject = new Object();
@Transactional(propagation = Propagation.REQUIRES_NEW)
public Long getNextAccount(String hostport) {
synchronized (lockObject) {
Long acc = null;
try {
AccountFetch dtls = getAccount();
if (dtls != null) {
acc = dtls.getAccId();
//Set IN_PROGRESS
dtls.setStatus("Progress");
dtls.saveAndFlush(dtls);
return acc;
} else {
log.info("No More Accounts to Process");
}
} catch (Exception e) {
e.getStackTrace();
}
return acc;
}
}
@Autowired
private AccService accSevice;
@GET
@Path("/accprocess")
@Produces(MediaType.APPLICATION_JSON)
public AccountFetch getAccId(@QueryParam("currentHost") final String currentHost,
@QueryParam("currentPort") final String currentPort) {
AccountFetch dtls = new AccountFetch();
try {
Long batchId = accSevice. getNextAccount(currentHost+"#"+currentPort);
if (accId != null) {
dtls.setAccId(String.valueOf(accId));
} else {
dtls.setAccId(BLANK_STRING);
}
} catch (Exception e) {
log.error("Exception while getting accId : " + e.getMessage());
}
return dtls;
}
public AccountFetch getAccount(){...}
Upvotes: 0
Views: 57
Reputation: 719679
A synchronized
block will only give you mutual exclusion if the threads are on the same host, and if they are locking using the same lock object.
Based on what you originally wrote in your question, it seems that one or both of these preconditions is not satisfied. If (as it now transpires) there is only one host processing these requests, then we must consider the other possibility; i.e. that there multiple instances of the AccService
object processing requests.
It is also possible that synchronization is working, and the problem is somewhere else. For example, getAccount()
could be returning the same account on successive calls.
Basically, there are too many parts of your code-base that we can't see. This means that we can only theorize as to what is causing the problem. If every thing was done correctly; i.e.
getAccount()
is implemented correctly, andgetAccount
without proper synchronization,then the code you have shown us would work.
If you need more help, an MCVE is probably required.
Upvotes: 1