improve race condition handling
This commit is contained in:
@@ -46,6 +46,10 @@ public class StewardIntegrationProcessor implements TransactionProcessorInterfac
|
|||||||
@Transactional
|
@Transactional
|
||||||
public Object process(Transaction transaction) throws Exception {
|
public Object process(Transaction transaction) throws Exception {
|
||||||
|
|
||||||
|
if(settingService.getBooleanSetting("SIMULATE_INTEGRATION_DELAY")){
|
||||||
|
Thread.sleep(5000);
|
||||||
|
}
|
||||||
|
|
||||||
if(settingService.getBooleanSetting("SIMULATE_INTEGRATION_FAILURE")){
|
if(settingService.getBooleanSetting("SIMULATE_INTEGRATION_FAILURE")){
|
||||||
transaction.setStatus(Status.FAILED);
|
transaction.setStatus(Status.FAILED);
|
||||||
transaction.setResponseCode("92");
|
transaction.setResponseCode("92");
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ import zw.qantra.tm.domain.services.processors.TransactionProcessorInterface;
|
|||||||
import zw.qantra.tm.exceptions.ApiException;
|
import zw.qantra.tm.exceptions.ApiException;
|
||||||
import zw.qantra.tm.utils.Utils;
|
import zw.qantra.tm.utils.Utils;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Service("integration")
|
@Service("integration")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class IntegrationHandler implements HandlerInterface {
|
public class IntegrationHandler implements HandlerInterface {
|
||||||
@@ -26,6 +29,8 @@ public class IntegrationHandler implements HandlerInterface {
|
|||||||
private final TransactionEventService transactionEventService;
|
private final TransactionEventService transactionEventService;
|
||||||
private final TransactionService transactionService;
|
private final TransactionService transactionService;
|
||||||
|
|
||||||
|
List<String> lock = new ArrayList<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object process(Transaction transaction) throws Exception {
|
public Object process(Transaction transaction) throws Exception {
|
||||||
transaction.setType(RequestType.INTEGRATION);
|
transaction.setType(RequestType.INTEGRATION);
|
||||||
@@ -34,6 +39,14 @@ public class IntegrationHandler implements HandlerInterface {
|
|||||||
if(transaction.getIntegrationStatus().equals(Status.SUCCESS))
|
if(transaction.getIntegrationStatus().equals(Status.SUCCESS))
|
||||||
return transaction;
|
return transaction;
|
||||||
|
|
||||||
|
// prevent race condition
|
||||||
|
if (isLocked(transaction.getId().toString())) {
|
||||||
|
logger.info("Transaction already processing - {}", transaction.getId());
|
||||||
|
transaction.setStatus(Status.PROCESSING);
|
||||||
|
return transaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
addLock(transaction.getId().toString());
|
||||||
TransactionEvent transactionEvent = TransactionEvent.builder()
|
TransactionEvent transactionEvent = TransactionEvent.builder()
|
||||||
.transactionId(transaction.getId().toString())
|
.transactionId(transaction.getId().toString())
|
||||||
.event(transaction.getType().name())
|
.event(transaction.getType().name())
|
||||||
@@ -70,6 +83,7 @@ public class IntegrationHandler implements HandlerInterface {
|
|||||||
|
|
||||||
transaction.setIntegrationStatus(transaction.getStatus());
|
transaction.setIntegrationStatus(transaction.getStatus());
|
||||||
|
|
||||||
|
removeLock(transaction.getId().toString());
|
||||||
if(transaction.getStatus() != Status.SUCCESS){
|
if(transaction.getStatus() != Status.SUCCESS){
|
||||||
transactionService.save(transaction);
|
transactionService.save(transaction);
|
||||||
throw new ApiException("Transaction failed: " + transaction.getErrorMessage() );
|
throw new ApiException("Transaction failed: " + transaction.getErrorMessage() );
|
||||||
@@ -84,4 +98,16 @@ public class IntegrationHandler implements HandlerInterface {
|
|||||||
transactionService.save(transaction);
|
transactionService.save(transaction);
|
||||||
return t1;
|
return t1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addLock(String uid) {
|
||||||
|
lock.add(uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean removeLock(String uid) {
|
||||||
|
return lock.remove(uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isLocked(String uid) {
|
||||||
|
return lock.contains(uid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
sbz.merchant.url=http://localhost:24000/v1
|
#sbz.merchant.url=http://localhost:24000/v1
|
||||||
#sbz.merchant.url=https://api.stewardpay.co.zw/lab/v2
|
sbz.merchant.url=https://api.stewardpay.co.zw/lab/v2
|
||||||
|
|
||||||
#spring.datasource.url=jdbc:postgresql://localhost:5432/qpay?useLegacyDatetimeCode=false
|
spring.datasource.url=jdbc:postgresql://localhost:5432/qpay?useLegacyDatetimeCode=false
|
||||||
#spring.datasource.username=postgres
|
spring.datasource.username=postgres
|
||||||
#spring.datasource.password=example
|
spring.datasource.password=example
|
||||||
|
|
||||||
#nflow.db.postgresql.driver=org.postgresql.Driver
|
nflow.db.postgresql.driver=org.postgresql.Driver
|
||||||
#nflow.db.postgresql.url=jdbc:postgresql://localhost:5432/qpay
|
nflow.db.postgresql.url=jdbc:postgresql://localhost:5432/qpay
|
||||||
#nflow.db.postgresql.user=postgres
|
nflow.db.postgresql.user=postgres
|
||||||
#nflow.db.postgresql.password=example
|
nflow.db.postgresql.password=example
|
||||||
Reference in New Issue
Block a user