improve race condition handling

This commit is contained in:
2025-11-05 11:00:47 +02:00
parent faa2ab17cf
commit eeb3e042ab
3 changed files with 39 additions and 9 deletions

View File

@@ -46,6 +46,10 @@ public class StewardIntegrationProcessor implements TransactionProcessorInterfac
@Transactional
public Object process(Transaction transaction) throws Exception {
if(settingService.getBooleanSetting("SIMULATE_INTEGRATION_DELAY")){
Thread.sleep(5000);
}
if(settingService.getBooleanSetting("SIMULATE_INTEGRATION_FAILURE")){
transaction.setStatus(Status.FAILED);
transaction.setResponseCode("92");

View File

@@ -15,6 +15,9 @@ import zw.qantra.tm.domain.services.processors.TransactionProcessorInterface;
import zw.qantra.tm.exceptions.ApiException;
import zw.qantra.tm.utils.Utils;
import java.util.ArrayList;
import java.util.List;
@Service("integration")
@RequiredArgsConstructor
public class IntegrationHandler implements HandlerInterface {
@@ -26,6 +29,8 @@ public class IntegrationHandler implements HandlerInterface {
private final TransactionEventService transactionEventService;
private final TransactionService transactionService;
List<String> lock = new ArrayList<>();
@Override
public Object process(Transaction transaction) throws Exception {
transaction.setType(RequestType.INTEGRATION);
@@ -34,6 +39,14 @@ public class IntegrationHandler implements HandlerInterface {
if(transaction.getIntegrationStatus().equals(Status.SUCCESS))
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()
.transactionId(transaction.getId().toString())
.event(transaction.getType().name())
@@ -70,6 +83,7 @@ public class IntegrationHandler implements HandlerInterface {
transaction.setIntegrationStatus(transaction.getStatus());
removeLock(transaction.getId().toString());
if(transaction.getStatus() != Status.SUCCESS){
transactionService.save(transaction);
throw new ApiException("Transaction failed: " + transaction.getErrorMessage() );
@@ -84,4 +98,16 @@ public class IntegrationHandler implements HandlerInterface {
transactionService.save(transaction);
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);
}
}

View File

@@ -1,11 +1,11 @@
sbz.merchant.url=http://localhost:24000/v1
#sbz.merchant.url=https://api.stewardpay.co.zw/lab/v2
#sbz.merchant.url=http://localhost:24000/v1
sbz.merchant.url=https://api.stewardpay.co.zw/lab/v2
#spring.datasource.url=jdbc:postgresql://localhost:5432/qpay?useLegacyDatetimeCode=false
#spring.datasource.username=postgres
#spring.datasource.password=example
spring.datasource.url=jdbc:postgresql://localhost:5432/qpay?useLegacyDatetimeCode=false
spring.datasource.username=postgres
spring.datasource.password=example
#nflow.db.postgresql.driver=org.postgresql.Driver
#nflow.db.postgresql.url=jdbc:postgresql://localhost:5432/qpay
#nflow.db.postgresql.user=postgres
#nflow.db.postgresql.password=example
nflow.db.postgresql.driver=org.postgresql.Driver
nflow.db.postgresql.url=jdbc:postgresql://localhost:5432/qpay
nflow.db.postgresql.user=postgres
nflow.db.postgresql.password=example