diff --git a/src/main/java/net/openhft/chronicle/map/acid/ChronicleAcidIsolationGovernor.java b/src/main/java/net/openhft/chronicle/map/acid/ChronicleAcidIsolationGovernor.java index fa5854366..af671d2f0 100644 --- a/src/main/java/net/openhft/chronicle/map/acid/ChronicleAcidIsolationGovernor.java +++ b/src/main/java/net/openhft/chronicle/map/acid/ChronicleAcidIsolationGovernor.java @@ -35,7 +35,12 @@ public class ChronicleAcidIsolationGovernor implements ChronicleAcidIsolation { //here is where the drama happens public synchronized BondVOInterface get(String cusip) throws Exception { - + System.out.println( + " ---------- @t="+System.currentTimeMillis()+ + " Tx="+Thread.currentThread()+ + " m.get()"+ + "---------- " + ); BondVOInterface b = null; Thread tx = Thread.currentThread(); ChronicleMap txMap = this.getTransactionIsolationMap(); @@ -43,13 +48,30 @@ public class ChronicleAcidIsolationGovernor implements ChronicleAcidIsolation { if (txMap.get(tx) <= ChronicleAcidIsolation.DIRTY_READ_OPTIMISTIC) { b = this.compositeChronicleMap.get(cusip); } else if (txMap.get(tx) >= ChronicleAcidIsolation.DIRTY_READ_INTOLERANT) { + System.out.println( + " ---------- @t="+System.currentTimeMillis()+ + " Tx="+Thread.currentThread()+ + " m.get() WAITING"+ + "---------- " + ); this.wait(); + System.out.println( + " ---------- @t="+System.currentTimeMillis()+ + " Tx="+Thread.currentThread()+ + " m.get() RESUMING"+ + "---------- " + ); b = this.compositeChronicleMap.get(cusip); } } else { b = this.compositeChronicleMap.get(cusip); } - + System.out.println( + " ---------- @t="+System.currentTimeMillis()+ + " Tx="+Thread.currentThread()+ + " m.get() DONE"+ + "---------- " + ); return b; } @@ -90,19 +112,56 @@ public class ChronicleAcidIsolationGovernor implements ChronicleAcidIsolation { @Override public synchronized void commit() throws SQLException { - + System.out.println( + " ---------- @t="+System.currentTimeMillis()+ + " Tx="+Thread.currentThread()+ + " chrAig.commit() BEGIN "+ + "---------- " + ); this.getTransactionIsolationMap().remove(Thread.currentThread()); + System.out.println( + " ---------- @t="+System.currentTimeMillis()+ + " Tx="+Thread.currentThread()+ + " chrAig.commit() END "+ + "---------- " + ); this.notifyAll(); + System.out.println( + " ---------- @t="+System.currentTimeMillis()+ + " Tx="+Thread.currentThread()+ + " chrAig.commit() complete notifyAll() to waiting Tx Threads "+ + "---------- " + ); } @Override public synchronized void rollback() throws SQLException { - BondVOInterface priorBond = this.compositeChronicleMap.get(priorCusip); - priorBond.setCoupon(priorCoupon); - this.getCompositeChronicleMap().put(priorCusip,priorBond); + BondVOInterface priorBond = this.getCompositeChronicleMap().get("369604101"); + if (priorBond != null) { + priorBond.setCoupon(priorCoupon); + this.getCompositeChronicleMap().put("369604101", priorBond); + } + System.out.println( + " ---------- @t="+System.currentTimeMillis()+ + " Tx="+Thread.currentThread()+ + " chrAig.rollback() BEGIN "+ + "---------- " + ); this.getTransactionIsolationMap().remove(Thread.currentThread()); + System.out.println( + " ---------- @t="+System.currentTimeMillis()+ + " Tx="+Thread.currentThread()+ + " chrAig.rollback() COMPLETE "+ + "---------- " + ); this.notifyAll(); + System.out.println( + " ---------- @t="+System.currentTimeMillis()+ + " Tx="+Thread.currentThread()+ + " chrAig.rollback() completed notifyAll() to waiting Tx Threads"+ + "---------- " + ); } // rest of these java.sql.Connection methods remain unimplemented ... // pedantics are too diff --git a/src/test/java/net/openhft/chronicle/map/fromdocs/acid/DirtyReadIntolerant.java b/src/test/java/net/openhft/chronicle/map/fromdocs/acid/DirtyReadIntolerant.java index 725ca1245..2213fb87a 100644 --- a/src/test/java/net/openhft/chronicle/map/fromdocs/acid/DirtyReadIntolerant.java +++ b/src/test/java/net/openhft/chronicle/map/fromdocs/acid/DirtyReadIntolerant.java @@ -29,16 +29,17 @@ public class DirtyReadIntolerant { DirtyReadIntolerant.acquireChronicleMapOperator( "C:\\Users\\buddy\\dev\\shm\\OPERATOR_CHRONICLE_MAP" ); - ChronicleAcidIsolationGovernor craig = new ChronicleAcidIsolationGovernor(); - craig.setCompositeChronicleMap(operand); - craig.setAutoCommit(Boolean.FALSE); - craig.setTransactionIsolationMap(operator); + ChronicleAcidIsolationGovernor chrAig = new ChronicleAcidIsolationGovernor(); + chrAig.setCompositeChronicleMap(operand); + chrAig.setAutoCommit(Boolean.FALSE); + chrAig.setTransactionIsolationMap(operator); + System.out.println("Established chrAig"); DirtyReadOffender offender = new DirtyReadOffender(); - offender.setCraig(craig); + offender.setCraig(chrAig); DirtyReadVictim victim = new DirtyReadVictim(); - victim.setCraig(craig); + victim.setCraig(chrAig); (new Thread(offender)).start(); (new Thread(victim)).start(); diff --git a/src/test/java/net/openhft/chronicle/map/fromdocs/acid/DirtyReadOffender.java b/src/test/java/net/openhft/chronicle/map/fromdocs/acid/DirtyReadOffender.java index f8dcd720a..92378c18d 100644 --- a/src/test/java/net/openhft/chronicle/map/fromdocs/acid/DirtyReadOffender.java +++ b/src/test/java/net/openhft/chronicle/map/fromdocs/acid/DirtyReadOffender.java @@ -5,35 +5,59 @@ import net.openhft.chronicle.map.acid.ChronicleAcidIsolationGovernor; import net.openhft.chronicle.map.acid.BondVOInterface; import java.sql.SQLException; +import java.util.Scanner; import static net.openhft.chronicle.values.Values.newNativeReference; public class DirtyReadOffender implements Runnable { - ChronicleAcidIsolationGovernor chraig; + ChronicleAcidIsolationGovernor chrAig; public ChronicleAcidIsolationGovernor getCraig() { - return chraig; + return chrAig; } public void setCraig(ChronicleAcidIsolationGovernor craig) { - this.chraig = craig; + this.chrAig = craig; } @Override public void run() { + Scanner sc = new Scanner(System.in); try { BondVOInterface bond = newNativeReference(BondVOInterface.class); - chraig.getCompositeChronicleMap().acquireUsing("369604101", bond); - chraig.setTransactionIsolation(ChronicleAcidIsolation.LOWEST_LATENCY); + chrAig.getCompositeChronicleMap().acquireUsing("369604101", bond); + System.out.println( + " @t=" + System.currentTimeMillis() + + " DirtyReadOffender calling chrAig.put('369604101',4.55) ---------- " + ); + //sc.nextLine(); + chrAig.setTransactionIsolation(ChronicleAcidIsolation.LOWEST_LATENCY); bond.setCoupon(4.55); - chraig.put("369604101",bond); - chraig.commit(); + chrAig.put("369604101", bond); + System.out.println( + " @t=" + System.currentTimeMillis() + + " DirtyReadOffender calling chrAig.commit() ---------- " + ); + sc.nextLine(); + chrAig.commit(); + System.out.println( + " @t=" + System.currentTimeMillis() + + " DirtyReadOffender COMMITTED ---------- " + ); } catch (Exception throwables) { try { - chraig.rollback(); + System.out.println( + " @t=" + System.currentTimeMillis() + + " DirtyReadOffender calling chrAig.rollback ---------- " + ); + chrAig.rollback(); + System.out.println( + " @t=" + System.currentTimeMillis() + + " DirtyReadOffender ROLLED BACK---------- " + ); } catch (SQLException e) { e.printStackTrace(); } diff --git a/src/test/java/net/openhft/chronicle/map/fromdocs/acid/DirtyReadVictim.java b/src/test/java/net/openhft/chronicle/map/fromdocs/acid/DirtyReadVictim.java index b574e6b9a..a2c4a6361 100644 --- a/src/test/java/net/openhft/chronicle/map/fromdocs/acid/DirtyReadVictim.java +++ b/src/test/java/net/openhft/chronicle/map/fromdocs/acid/DirtyReadVictim.java @@ -6,34 +6,61 @@ import net.openhft.chronicle.map.acid.ChronicleAcidIsolation; import net.openhft.chronicle.map.acid.ChronicleAcidIsolationGovernor; import java.sql.SQLException; +import java.util.Scanner; import static net.openhft.chronicle.values.Values.newNativeReference; public class DirtyReadVictim implements Runnable { - ChronicleAcidIsolationGovernor craig; + ChronicleAcidIsolationGovernor chrAig; public ChronicleAcidIsolationGovernor getCraig() { - return craig; + + return this.chrAig; } public void setCraig(ChronicleAcidIsolationGovernor craig) { - this.craig = craig; + + this.chrAig = craig; } @Override public void run() { + Scanner sc= new Scanner(System.in); try { + Thread.sleep(10_000); BondVOInterface bond = newNativeReference(BondVOInterface.class); - craig.getCompositeChronicleMap().acquireUsing("369604101", bond); - - craig.setTransactionIsolation(ChronicleAcidIsolation.DIRTY_READ_INTOLERANT); - bond = craig.getCompositeChronicleMap().get("369604101"); + chrAig.getCompositeChronicleMap().acquireUsing("369604101", bond); + System.out.println( + " ---------- @t="+System.currentTimeMillis()+ + " DirtyReadVictim calling m.get('369604101')" + ); + //sc.nextLine(); + chrAig.setTransactionIsolation(ChronicleAcidIsolation.DIRTY_READ_INTOLERANT); + bond = chrAig.getCompositeChronicleMap().get("369604101"); Double coupon = bond.getCoupon(); - craig.commit(); + System.out.println( + " ---------- @t="+System.currentTimeMillis()+ + " DirtyReadVictim calling chrAig.commmit()" + ); + //sc.nextLine(); + chrAig.commit(); + System.out.println( + " ---------- @t="+System.currentTimeMillis()+ + " DirtyReadVictim COMMITTED" + ); } catch (Exception throwables) { try { - craig.rollback(); + System.out.println( + " ---------- @t="+System.currentTimeMillis()+ + " DirtyReadVictim calling chrAig.rollback()" + ); + sc.nextLine(); + chrAig.rollback(); + System.out.println( + " ---------- @t="+System.currentTimeMillis()+ + " DirtyReadVictim ROLLED BACK" + ); } catch (SQLException e) { e.printStackTrace(); }