diff --git a/accession-commons-monotonic-generator-jpa/src/main/java/uk/ac/ebi/ampt2d/commons/accession/persistence/jpa/monotonic/service/ContiguousIdBlockService.java b/accession-commons-monotonic-generator-jpa/src/main/java/uk/ac/ebi/ampt2d/commons/accession/persistence/jpa/monotonic/service/ContiguousIdBlockService.java index 5f86d4e0..df355838 100644 --- a/accession-commons-monotonic-generator-jpa/src/main/java/uk/ac/ebi/ampt2d/commons/accession/persistence/jpa/monotonic/service/ContiguousIdBlockService.java +++ b/accession-commons-monotonic-generator-jpa/src/main/java/uk/ac/ebi/ampt2d/commons/accession/persistence/jpa/monotonic/service/ContiguousIdBlockService.java @@ -51,7 +51,11 @@ * (see method @reserveNewBlock) * * Also, when saving the blocks, we need to check for the block's last committed value. - * If it's last committed value is same as last value, we should release the block in DB + * If its last committed value is same as last value, we should release the block in DB. + * + * To guarantee safe multiprocessing in PostgreSQL, all methods in ContiguousIdBlockService that access the DB must use + * the SERIALIZABLE transaction isolation level. + * See here for details: https://wiki.postgresql.org/wiki/Serializable#PostgreSQL_Implementation * */ public class ContiguousIdBlockService { @@ -69,7 +73,7 @@ public ContiguousIdBlockService(ContiguousIdBlockRepository repository, Map blocks) { // release block if full blocks.forEach(block -> {if (block.isFull()) {block.releaseReserved();}}); @@ -77,7 +81,7 @@ public void save(Iterable blocks) { entityManager.flush(); } - @Transactional + @Transactional(isolation = Isolation.SERIALIZABLE) public void save(ContiguousIdBlock block) { // release block if full if (block.isFull()) {