mirror of
https://github.com/usatiuk/dhfs.git
synced 2025-10-28 20:47:49 +01:00
Objects: don't run tx commit hooks inside the same transaction
This commit is contained in:
@@ -54,7 +54,7 @@ public class JObjectManager {
|
||||
return tx;
|
||||
}
|
||||
|
||||
public TransactionHandle commit(TransactionPrivate tx) {
|
||||
public Pair<Collection<Runnable>, TransactionHandle> commit(TransactionPrivate tx) {
|
||||
verifyReady();
|
||||
var writes = new LinkedHashMap<JObjectKey, TxRecord.TxObjectRecord<?>>();
|
||||
var dependenciesLocked = new LinkedHashMap<JObjectKey, Optional<JDataVersionedWrapper>>();
|
||||
@@ -173,16 +173,17 @@ public class JObjectManager {
|
||||
if (writes.isEmpty()) {
|
||||
Log.trace("Committing transaction - no changes");
|
||||
|
||||
for (var callback : tx.getOnCommit()) {
|
||||
callback.run();
|
||||
}
|
||||
|
||||
return new TransactionHandle() {
|
||||
@Override
|
||||
public void onFlush(Runnable runnable) {
|
||||
runnable.run();
|
||||
}
|
||||
};
|
||||
return Pair.of(
|
||||
Stream.concat(
|
||||
tx.getOnCommit().stream(),
|
||||
tx.getOnFlush().stream()
|
||||
).toList(),
|
||||
new TransactionHandle() {
|
||||
@Override
|
||||
public void onFlush(Runnable runnable) {
|
||||
runnable.run();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Log.trace("Committing transaction start");
|
||||
@@ -224,20 +225,18 @@ public class JObjectManager {
|
||||
return true;
|
||||
}).toList());
|
||||
|
||||
for (var callback : tx.getOnCommit()) {
|
||||
callback.run();
|
||||
}
|
||||
|
||||
for (var callback : tx.getOnFlush()) {
|
||||
addFlushCallback.accept(callback);
|
||||
}
|
||||
|
||||
return new TransactionHandle() {
|
||||
@Override
|
||||
public void onFlush(Runnable runnable) {
|
||||
addFlushCallback.accept(runnable);
|
||||
}
|
||||
};
|
||||
return Pair.of(
|
||||
List.copyOf(tx.getOnCommit()),
|
||||
new TransactionHandle() {
|
||||
@Override
|
||||
public void onFlush(Runnable runnable) {
|
||||
addFlushCallback.accept(runnable);
|
||||
}
|
||||
});
|
||||
} catch (Throwable t) {
|
||||
Log.trace("Error when committing transaction", t);
|
||||
throw new TxCommitException(t.getMessage(), t);
|
||||
|
||||
@@ -3,6 +3,9 @@ package com.usatiuk.dhfs.objects.transaction;
|
||||
import io.quarkus.logging.Log;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.inject.Inject;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
@ApplicationScoped
|
||||
public class TransactionManagerImpl implements TransactionManager {
|
||||
@@ -28,8 +31,10 @@ public class TransactionManagerImpl implements TransactionManager {
|
||||
}
|
||||
|
||||
Log.trace("Committing transaction");
|
||||
|
||||
Pair<Collection<Runnable>, TransactionHandle> ret;
|
||||
try {
|
||||
return jObjectManager.commit(_currentTransaction.get());
|
||||
ret = jObjectManager.commit(_currentTransaction.get());
|
||||
} catch (Throwable e) {
|
||||
Log.trace("Transaction commit failed", e);
|
||||
throw e;
|
||||
@@ -37,6 +42,15 @@ public class TransactionManagerImpl implements TransactionManager {
|
||||
_currentTransaction.get().close();
|
||||
_currentTransaction.remove();
|
||||
}
|
||||
|
||||
for (var r : ret.getLeft()) {
|
||||
try {
|
||||
r.run();
|
||||
} catch (Throwable e) {
|
||||
Log.error("Transaction commit hook error: ", e);
|
||||
}
|
||||
}
|
||||
return ret.getRight();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -69,6 +69,30 @@ public abstract class ObjectsTestImpl {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void onCommitHookTest() {
|
||||
txm.run(() -> {
|
||||
var newParent = new Parent(JObjectKey.of("ParentOnCommitHook"), "John");
|
||||
curTx.put(newParent);
|
||||
curTx.onCommit(() -> txm.run(() -> {
|
||||
curTx.put(new Parent(JObjectKey.of("ParentOnCommitHook2"), "John2"));
|
||||
}));
|
||||
});
|
||||
txm.run(() -> {
|
||||
curTx.onCommit(() -> txm.run(() -> {
|
||||
curTx.put(new Parent(JObjectKey.of("ParentOnCommitHook3"), "John3"));
|
||||
}));
|
||||
});
|
||||
txm.run(() -> {
|
||||
var parent = curTx.get(Parent.class, new JObjectKey("ParentOnCommitHook")).orElse(null);
|
||||
Assertions.assertEquals("John", parent.name());
|
||||
var parent2 = curTx.get(Parent.class, new JObjectKey("ParentOnCommitHook2")).orElse(null);
|
||||
Assertions.assertEquals("John2", parent2.name());
|
||||
var parent3 = curTx.get(Parent.class, new JObjectKey("ParentOnCommitHook3")).orElse(null);
|
||||
Assertions.assertEquals("John3", parent3.name());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void createGetObject() {
|
||||
txm.run(() -> {
|
||||
|
||||
Reference in New Issue
Block a user