diff --git a/dhfs-parent/objects/src/main/java/com/usatiuk/dhfs/objects/JObjectManager.java b/dhfs-parent/objects/src/main/java/com/usatiuk/dhfs/objects/JObjectManager.java index 05192f14..406f06e1 100644 --- a/dhfs-parent/objects/src/main/java/com/usatiuk/dhfs/objects/JObjectManager.java +++ b/dhfs-parent/objects/src/main/java/com/usatiuk/dhfs/objects/JObjectManager.java @@ -186,6 +186,7 @@ public class JObjectManager { var current = new LinkedHashMap>(); var dependenciesLocked = new LinkedHashMap>(); + Map> reads; var toUnlock = new ArrayList(); Consumer addDependency = @@ -220,8 +221,6 @@ public class JObjectManager { try { Collection> drained; while (!(drained = tx.drainNewWrites()).isEmpty()) { - var toLock = new ArrayList(); - Log.trace("Commit iteration with " + drained.size() + " records"); drained.stream() @@ -249,7 +248,8 @@ public class JObjectManager { } } - for (var read : tx.reads().entrySet()) { + reads = tx.reads(); + for (var read : reads.entrySet()) { addDependency.accept(read.getKey()); if (read.getValue() instanceof TransactionObjectLocked locked) { toUnlock.add(locked.lock); @@ -257,13 +257,23 @@ public class JObjectManager { } for (var dep : dependenciesLocked.entrySet()) { - Log.trace("Checking dependency " + dep.getKey()); - - if (dep.getValue().data().isEmpty()) continue; + if (dep.getValue().data().isEmpty()) { + Log.trace("Checking dependency " + dep.getKey() + " - not found"); + continue; + } if (dep.getValue().data().get().version() >= tx.getId()) { + Log.trace("Checking dependency " + dep.getKey() + " - newer than"); throw new IllegalStateException("Serialization hazard: " + dep.getValue().data().get().version() + " vs " + tx.getId()); } + + var read = reads.get(dep.getKey()); + if (read != null && read.data().orElse(null) != dep.getValue().data().orElse(null)) { + Log.trace("Checking dependency " + dep.getKey() + " - read mismatch"); + throw new IllegalStateException("Read mismatch for " + dep.getKey() + ": " + read + " vs " + dep.getValue()); + } + + Log.trace("Checking dependency " + dep.getKey() + " - ok"); } Log.tracef("Flushing transaction %d to storage", tx.getId()); diff --git a/dhfs-parent/objects/src/test/java/com/usatiuk/dhfs/objects/ObjectsTest.java b/dhfs-parent/objects/src/test/java/com/usatiuk/dhfs/objects/ObjectsTest.java index d6f93676..2298d491 100644 --- a/dhfs-parent/objects/src/test/java/com/usatiuk/dhfs/objects/ObjectsTest.java +++ b/dhfs-parent/objects/src/test/java/com/usatiuk/dhfs/objects/ObjectsTest.java @@ -158,6 +158,7 @@ public class ObjectsTest { Log.warn("Thread 1"); txm.begin(); barrier.await(); + var got = curTx.get(Parent.class, new JObjectKey("Parent2")).orElse(null); var newParent = new Parent(JObjectKey.of("Parent2"), "John"); curTx.put(newParent); Log.warn("Thread 1 commit"); @@ -173,6 +174,7 @@ public class ObjectsTest { Log.warn("Thread 2"); txm.begin(); barrier.await(); + var got = curTx.get(Parent.class, new JObjectKey("Parent2")).orElse(null); var newParent = new Parent(JObjectKey.of("Parent2"), "John2"); curTx.put(newParent); Log.warn("Thread 2 commit");