package jnpf.flowable.service;
|
|
import com.baomidou.dynamic.datasource.tx.*;
|
import org.junit.After;
|
import org.junit.Test;
|
import java.util.concurrent.atomic.AtomicInteger;
|
import static org.junit.Assert.*;
|
|
/** Uses the installed dynamic-datasource transaction executor, not a simulated callback loader. */
|
public class DmsLifecycleEngineCompensationTest {
|
@After public void cleanup() {TransactionContext.remove();TransactionContext.removeSynchronizations();}
|
private void transaction(Runnable work) throws Throwable {
|
var info=new TransactionalInfo();info.setPropagation(DsPropagation.REQUIRED);
|
info.setRollbackFor(new Class[]{Exception.class});info.setNoRollbackFor(new Class[]{});
|
new TransactionalTemplate().execute(new TransactionalExecutor() {
|
public Object execute() {work.run();return null;}
|
public TransactionalInfo getTransactionInfo() {return info;}
|
});
|
}
|
@Test public void successfulCommitRetainsEngineInstance() throws Throwable {
|
var deleted=new AtomicInteger();
|
transaction(()->DmsLifecycleEngineCompensation.register("engine",deleted::incrementAndGet));
|
assertEquals(0,deleted.get());assertTrue(TransactionContext.getSynchronizations().isEmpty());
|
}
|
@Test public void laterFailureRollsBackEveryPreviouslyStartedDmsInstance() throws Throwable {
|
var deleted=new AtomicInteger();
|
try {
|
transaction(()->{
|
DmsLifecycleEngineCompensation.register("first",deleted::incrementAndGet);
|
DmsLifecycleEngineCompensation.register("second",deleted::incrementAndGet);
|
throw new IllegalStateException("later native save failed");
|
});fail();
|
} catch(IllegalStateException expected) { }
|
assertEquals(2,deleted.get());assertTrue(TransactionContext.getSynchronizations().isEmpty());
|
}
|
@Test public void immediateCompensationDoesNotDeleteTwiceOnRollback() throws Throwable {
|
var deleted=new AtomicInteger();
|
try {
|
transaction(()->{
|
var ticket=DmsLifecycleEngineCompensation.register("engine",deleted::incrementAndGet);
|
var failure=new IllegalStateException("configuration read failed");
|
ticket.compensate(failure);throw failure;
|
});fail();
|
} catch(IllegalStateException expected) { }
|
assertEquals(1,deleted.get());
|
}
|
@Test public void failedImmediateDeletionRetriesAtOuterRollback() throws Throwable {
|
var attempts=new AtomicInteger();var failure=new IllegalArgumentException("native failure");
|
try {
|
transaction(()->{
|
var ticket=DmsLifecycleEngineCompensation.register("engine",()->{
|
if(attempts.incrementAndGet()==1) throw new IllegalStateException("temporary engine failure");
|
});ticket.compensate(failure);throw failure;
|
});fail();
|
} catch(IllegalArgumentException expected) {assertSame(failure,expected);}
|
assertEquals(2,attempts.get());assertEquals(1,failure.getSuppressed().length);
|
}
|
}
|