mirror of
https://github.com/google/nomulus.git
synced 2025-04-29 19:47:51 +02:00
Transaction manager to not retry inner transactions (#1974)
This commit is contained in:
parent
33b43c05e7
commit
8d7088552f
2 changed files with 30 additions and 0 deletions
|
@ -154,6 +154,10 @@ public class JpaTransactionManagerImpl implements JpaTransactionManager {
|
|||
|
||||
@Override
|
||||
public <T> T transact(Supplier<T> work) {
|
||||
// This prevents inner transaction from retrying, thus avoiding a cascade retry effect.
|
||||
if (inTransaction()) {
|
||||
return transactNoRetry(work);
|
||||
}
|
||||
return retrier.callWithRetry(() -> transactNoRetry(work), JpaRetries::isFailedTxnRetriable);
|
||||
}
|
||||
|
||||
|
|
|
@ -580,6 +580,32 @@ class JpaTransactionManagerImplTest {
|
|||
.isFalse());
|
||||
}
|
||||
|
||||
@Test
|
||||
void innerTransactions_noRetry() {
|
||||
JpaTransactionManager spyJpaTm = spy(tm());
|
||||
doThrow(OptimisticLockException.class).when(spyJpaTm).delete(any(VKey.class));
|
||||
spyJpaTm.transact(() -> spyJpaTm.insert(theEntity));
|
||||
|
||||
Supplier<Runnable> supplier =
|
||||
() -> {
|
||||
Runnable work = () -> spyJpaTm.delete(theEntityKey);
|
||||
work.run();
|
||||
return null;
|
||||
};
|
||||
|
||||
assertThrows(
|
||||
OptimisticLockException.class,
|
||||
() ->
|
||||
spyJpaTm.transact(
|
||||
() -> {
|
||||
spyJpaTm.exists(theEntity);
|
||||
spyJpaTm.transact(supplier);
|
||||
}));
|
||||
|
||||
verify(spyJpaTm, times(3)).exists(theEntity);
|
||||
verify(spyJpaTm, times(3)).delete(theEntityKey);
|
||||
}
|
||||
|
||||
private void insertPerson(int age) {
|
||||
tm().getEntityManager()
|
||||
.createNativeQuery(String.format("INSERT INTO Person (age) VALUES (%d)", age))
|
||||
|
|
Loading…
Add table
Reference in a new issue