I'm trying to update the same row in two separate transactions that I'm managing programmatically.
Here is the test:
@Sql("classpath:sql/balance/account_with_balance_EE.sql")
@Test
void changeNoLock() {
long balanceId = 10000L;
DefaultTransactionDefinition firstTransactionDefinition = new DefaultTransactionDefinition();
DefaultTransactionDefinition secondTransactionDefinition = new DefaultTransactionDefinition();
firstTransactionDefinition.setName("firstTransaction");
secondTransactionDefinition.setName("secondTransaction");
firstTransactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
secondTransactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
TransactionStatus firstTransactionStatus = txManager.getTransaction(firstTransactionDefinition);
balanceService.change(balanceId, BigDecimal.ONE);
TransactionStatus secondTransactionStatus = txManager.getTransaction(secondTransactionDefinition);
balanceService.change(balanceId, BigDecimal.ONE);
txManager.commit(firstTransactionStatus);
txManager.commit(secondTransactionStatus);
BalanceDto balanceDto = balanceService.find(balanceId);
assertEquals(new BigDecimal("2.00"), balanceDto.getBalanceAmount());
}
balanceService#change method is transactional with default propagation and default isolation.
When I run this test it's just hanging, the only time it doesn't hang is when I commit first transaction before starting the second why. Why is this happening?
I'm using Java 17 with Spring boot 3 and a Postgres database.
Looks like you have deadlocks, you could create a retry mechanism to handle deadlock situations, and catch deadlock exceptions and retry the transactions after a delay
Or a simplified and with best performance version