I'm trying to lock an jpa entity while i work with it, so it cannot be read/writen during this method invocation. But my testing shows the lock is not working righ Using spring-boot-starter-data-jpa, hibernate and postgresql.
This is the method:
public BalanceJournal addCreditsBankDeposit(
Long licenseId,
String userId,
Integer credits) {
return addCredits(
BalanceJournalType.BANK_DEPOSIT,
licenseId,
userId,
credits
);
}
@Transactional(isolation = Isolation.SERIALIZABLE)
protected BalanceJournal addCredits(
BalanceJournalType type,
Long licenseId,
String userId,
Integer credits) {
//While this method running i need this license entity not to be readable
License license = licenseRepo.findById(licenseId);
BalanceJournal journal = balanceJournalRepo.save(new BalanceJournal()
.withBalance(license.getBalanceTotal() + credits)
.withCredit(credits)
.withDebit(0)
.withEntryTs(LocalDateTime.now())
.withEntryType(type)
.withsLicense(licenseId)
.withLicenseUser(userId));
licenseRepo.save(license.withBalanceTotal(journal.getBalance()));
//when this method returns or throws exception, the license should be readable again.
return journal;
}
My Repo classes are just JpaRepositories from Spring-Data
public interface BalanceJournalRepository extends JpaRepository<BalanceJournal, Long> {
}
I'm testing this out like this
final ExecutorService executor = Executors.newFixedThreadPool(5);
for (int i = 1; i <= 5; i++) {
final int amount = i;
executor.execute(() -> balanceJournalService.addCreditsBankDeposit(licenseId, userId, amount));
}
executor.shutdown();
executor.awaitTermination(1, TimeUnit.MINUTES);
Before starting the test my license.balance = 0, and i have no journals. At the end i would expect to have my licence.balance = 15 (1+2+3+4+5) and 5 journals like:
1) credit=1, balance=1
2) credit=2, balance=3
3) credit=3, balance=6
4) credit=4, balance=10
5) credit=5, balance=15
But i end up with license.balance = 5
1) credit=1, balance=1
2) credit=2, balance=2
3) credit=3, balance=3
4) credit=4, balance=4
5) credit=5, balance=5
¿How can i acomplish the expected result?