diff --git a/dhfs-parent/objects/src/main/java/com/usatiuk/dhfs/objects/transaction/JObjectManager.java b/dhfs-parent/objects/src/main/java/com/usatiuk/dhfs/objects/transaction/JObjectManager.java index 2310a6f5..b1f863cd 100644 --- a/dhfs-parent/objects/src/main/java/com/usatiuk/dhfs/objects/transaction/JObjectManager.java +++ b/dhfs-parent/objects/src/main/java/com/usatiuk/dhfs/objects/transaction/JObjectManager.java @@ -54,7 +54,7 @@ public class JObjectManager { return tx; } - public TransactionHandle commit(TransactionPrivate tx) { + public Pair, TransactionHandle> commit(TransactionPrivate tx) { verifyReady(); var writes = new LinkedHashMap>(); var dependenciesLocked = new LinkedHashMap>(); @@ -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); diff --git a/dhfs-parent/objects/src/main/java/com/usatiuk/dhfs/objects/transaction/TransactionManagerImpl.java b/dhfs-parent/objects/src/main/java/com/usatiuk/dhfs/objects/transaction/TransactionManagerImpl.java index 6727c8b6..e22113e1 100644 --- a/dhfs-parent/objects/src/main/java/com/usatiuk/dhfs/objects/transaction/TransactionManagerImpl.java +++ b/dhfs-parent/objects/src/main/java/com/usatiuk/dhfs/objects/transaction/TransactionManagerImpl.java @@ -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, 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 diff --git a/dhfs-parent/objects/src/test/java/com/usatiuk/dhfs/objects/ObjectsTestImpl.java b/dhfs-parent/objects/src/test/java/com/usatiuk/dhfs/objects/ObjectsTestImpl.java index 80d03674..87b9e290 100644 --- a/dhfs-parent/objects/src/test/java/com/usatiuk/dhfs/objects/ObjectsTestImpl.java +++ b/dhfs-parent/objects/src/test/java/com/usatiuk/dhfs/objects/ObjectsTestImpl.java @@ -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(() -> {