From 8b977ea3b6c78b1f2ba1675765f92772df4d6e4e Mon Sep 17 00:00:00 2001 From: cotton-ben Date: Thu, 7 May 2020 08:36:25 -0400 Subject: [PATCH] renders 2 spread sheets that demonstrate DIRTY_READ tolerance outcomes when interacting with ChronicleMap optimistically (and with INTOLERANCE) --- intolerant.csv | 41 ++++++++------- .../acid/ChronicleAcidIsolationGovernor.java | 50 +++++++++++-------- .../map/fromdocs/acid/DirtyReadOffender.java | 35 +++++++------ .../map/fromdocs/acid/DirtyReadTolerance.java | 2 +- .../map/fromdocs/acid/DirtyReadVictim.java | 20 ++++---- 5 files changed, 79 insertions(+), 69 deletions(-) diff --git a/intolerant.csv b/intolerant.csv index 792a0a6a0..0403e927e 100644 --- a/intolerant.csv +++ b/intolerant.csv @@ -1,20 +1,23 @@ +DirtyReadOffender,chrAig[DIRTY_READ_INTOLERANT]coupon=3.50,DirtyReadVictim ,Established chrAig, - ,,---------- @t=1588525918726 DirtyReadVictim sleeping 10 seconds - @t=1588525918775 DirtyReadOffender calling chrAig.put('369604101',4.55) ----------, - ,---------- @t=1588525918777 Tx=Thread[Thread-4.5.main] inside chrAig.put('369604101'/4.55) DONE----------, - @t=1588525918777 DirtyReadOffender sleeping 1 minute. ----------,, - ,,---------- @t=1588525928747 DirtyReadVictim calling chrAig.get('369604101') - ,---------- @t=1588525928747 Tx=Thread[Thread-5.5.main] inside chrAig.get('369604101') BEGIN----------, -, ---------- @t=1588525928762 Tx=Thread[Thread-5.5.main] inside chrAig.get() WAITING---------- , - @t=1588525978781 DirtyReadOffender calling chrAig.rollback() ----------,, - ,---------- @t=1588525978781 Tx=Thread[Thread-4.5.main] chrAig.rollback() BEGIN ----------, - ,---------- @t=1588525978781 Tx=Thread[Thread-4.5.main] chrAig.rollback() COMPLETE ----------, -, ---------- @t=1588525978781 Tx=Thread[Thread-4.5.main] chrAig.rollback() completed notifyAll() to waiting Tx Threads----------, - ,---------- @t=1588525978781 Tx=Thread[Thread-5.5.main] inside chrAig.get() RESUMING----------, - @t=1588525978781 DirtyReadOffender ROLLED BACK ----------,, - ,---------- @t=1588525978781 Tx=Thread[Thread-5.5.main] inside chrAig.get() DONE---------- , - ,,---------- @t=1588525978781 DirtyReadVictim got() coupon=3.5 calling chrAig.commmit() - ,---------- @t=1588525978781 Tx=Thread[Thread-5.5.main] chrAig.commit() BEGIN ----------, - ,---------- @t=1588525978781 Tx=Thread[Thread-5.5.main] chrAig.commit() END ----------, -, ---------- @t=1588525978781 Tx=Thread[Thread-5.5.main] chrAig.commit() complete notifyAll() to waiting Tx Threads ---------- , - ,,---------- @t=1588525978781 DirtyReadVictim COMMITTED + ,,@t=1588854013435 DirtyReadVictim sleeping 10 seconds + @t=1588854013450 DirtyReadOffender calling chrAig.put('369604101'/3.85) ,, + , @t=1588854013450 Tx=Thread[Thread-4.5.main] inside chrAig.put('369604101'/null) BEGIN, + , @t=1588854013450 Tx=Thread[Thread-4.5.main] inside chrAig.put('369604101'/3.85) DONE, + @t=1588854013450 DirtyReadOffender sleeping 1 minute. ,, + ,,@t=1588854023448 DirtyReadVictim calling chrAig.get('369604101') + , @t=1588854023448 Tx=Thread[Thread-5.5.main] inside chrAig.get('369604101') BEGIN, +, @t=1588854023448 Tx=Thread[Thread-5.5.main] inside chrAig.get() WAITING , + @t=1588854073452 DirtyReadOffender calling chrAig.rollback() ,, + , @t=1588854073452 Tx=Thread[Thread-4.5.main] chrAig.rollback() BEGIN , + ,@t=1588854073452 Tx=Thread[Thread-4.5.main] chrAig.rollback() COMPLETE coupon=3.50, +, @t=1588854073452 Tx=Thread[Thread-4.5.main] chrAig.rollback() completed notifyAll() to waiting Tx Threads, + , @t=1588854073452 Tx=Thread[Thread-5.5.main] inside chrAig.get() RESUMING, + , @t=1588854073452 Tx=Thread[Thread-5.5.main] inside chrAig.get() DONE , + ,,@t=1588854073452 DirtyReadVictim got() coupon=3.5 + @t=1588854073452 DirtyReadOffender ROLLED BACK ,, + ,,@t=1588854073452 DirtyReadVictim calling chrAig.commmit() + ,@t=1588854073452 Tx=Thread[Thread-5.5.main] chrAig.commit() BEGIN , + , @t=1588854073452 Tx=Thread[Thread-5.5.main] chrAig.commit() END , +, @t=1588854073452 Tx=Thread[Thread-5.5.main] chrAig.commit() complete notifyAll() to waiting Tx Threads , + ,,@t=1588854073452 DirtyReadVictim COMMITTED 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 5f2935a1d..ef966d26a 100644 --- a/src/main/java/net/openhft/chronicle/map/acid/ChronicleAcidIsolationGovernor.java +++ b/src/main/java/net/openhft/chronicle/map/acid/ChronicleAcidIsolationGovernor.java @@ -24,16 +24,22 @@ public class ChronicleAcidIsolationGovernor implements ChronicleAcidIsolation { public synchronized void put(String cusip, BondVOInterface bond) throws Exception { + System.out.println( + " , @t="+System.currentTimeMillis()+ + " Tx="+Thread.currentThread().toString().replaceAll(",",".")+ + " inside chrAig.put('"+cusip+"'/"+aCoupon+") BEGIN"+ + ", " + ); ChronicleMap cMap = this.getCompositeChronicleMap(); this.aCoupon = cMap.get(cusip).getCoupon(); bond.setCoupon(aCoupon); cMap.put(cusip, bond); System.out.println( - " ,---------- @t="+System.currentTimeMillis()+ + " , @t="+System.currentTimeMillis()+ " Tx="+Thread.currentThread().toString().replaceAll(",",".")+ " inside chrAig.put('"+cusip+"'/"+aCoupon+") DONE"+ - "----------, " + ", " ); } @@ -41,10 +47,10 @@ 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()+ + " , @t="+System.currentTimeMillis()+ " Tx="+Thread.currentThread().toString().replaceAll(",",".")+ " inside chrAig.get('"+cusip+"') BEGIN"+ - "----------, " + ", " ); BondVOInterface b = null; String tx = Thread.currentThread().toString(); @@ -54,17 +60,17 @@ public class ChronicleAcidIsolationGovernor implements ChronicleAcidIsolation { b = this.compositeChronicleMap.get(cusip); } else if (txMap.get(tx) >= ChronicleAcidIsolation.DIRTY_READ_INTOLERANT) { System.out.println( - ", ---------- @t="+System.currentTimeMillis()+ + ", @t="+System.currentTimeMillis()+ " Tx="+Thread.currentThread().toString().replaceAll(",",".")+ " inside chrAig.get() WAITING"+ - "---------- ," + " ," ); this.wait(); System.out.println( - " ,---------- @t="+System.currentTimeMillis()+ + " , @t="+System.currentTimeMillis()+ " Tx="+Thread.currentThread().toString().replaceAll(",",".")+ " inside chrAig.get() RESUMING"+ - "----------, " + ", " ); b = this.compositeChronicleMap.get(cusip); } @@ -72,10 +78,10 @@ public class ChronicleAcidIsolationGovernor implements ChronicleAcidIsolation { b = this.compositeChronicleMap.get(cusip); } System.out.println( - " ,---------- @t="+System.currentTimeMillis()+ + " , @t="+System.currentTimeMillis()+ " Tx="+Thread.currentThread().toString().replaceAll(",",".")+ " inside chrAig.get() DONE"+ - "---------- ," + " ," ); return b; } @@ -121,21 +127,21 @@ public class ChronicleAcidIsolationGovernor implements ChronicleAcidIsolation { " ,@t="+System.currentTimeMillis()+ " Tx="+Thread.currentThread().toString().replaceAll(",",".")+ " chrAig.commit() BEGIN "+ - "----------, " + ", " ); this.getTransactionIsolationMap().remove(Thread.currentThread().toString()); System.out.println( - " ,---------- @t="+System.currentTimeMillis()+ + " , @t="+System.currentTimeMillis()+ " Tx="+Thread.currentThread().toString().replaceAll(",",".")+ " chrAig.commit() END "+ - "----------, " + ", " ); this.notifyAll(); System.out.println( - ", ---------- @t="+System.currentTimeMillis()+ + ", @t="+System.currentTimeMillis()+ " Tx="+Thread.currentThread().toString().replaceAll(",",".")+ " chrAig.commit() complete notifyAll() to waiting Tx Threads "+ - "---------- ," + "," ); } @@ -148,24 +154,24 @@ public class ChronicleAcidIsolationGovernor implements ChronicleAcidIsolation { this.getCompositeChronicleMap().put("369604101", priorBond); } System.out.println( - " ,---------- @t="+System.currentTimeMillis()+ + " , @t="+System.currentTimeMillis()+ " Tx="+Thread.currentThread().toString().replaceAll(",",".")+ " chrAig.rollback() BEGIN "+ - "----------, " + ", " ); this.getTransactionIsolationMap().remove(Thread.currentThread().toString()); System.out.println( - " ,---------- @t="+System.currentTimeMillis()+ + " ,@t="+System.currentTimeMillis()+ " Tx="+Thread.currentThread().toString().replaceAll(",",".")+ - " chrAig.rollback() COMPLETE "+ - "----------, " + " chrAig.rollback() COMPLETE coupon=3.50"+ + ", " ); this.notifyAll(); System.out.println( - ", ---------- @t="+System.currentTimeMillis()+ + ", @t="+System.currentTimeMillis()+ " Tx="+Thread.currentThread().toString().replaceAll(",",".")+ " chrAig.rollback() completed notifyAll() to waiting Tx Threads"+ - "----------, " + ", " ); } // rest of these java.sql.Connection methods remain unimplemented ... 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 04bb4cbd5..c12fbc78f 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 @@ -20,8 +20,7 @@ public class DirtyReadOffender implements Runnable { public void setCraig(ChronicleAcidIsolationGovernor craig) { this.chrAig = craig; } - - + @Override public void run() { Scanner sc = new Scanner(System.in); @@ -30,40 +29,40 @@ public class DirtyReadOffender implements Runnable { BondVOInterface bond = newNativeReference(BondVOInterface.class); chrAig.getCompositeChronicleMap().acquireUsing("369604101", bond); System.out.println( - " @t=" + System.currentTimeMillis() + - " DirtyReadOffender calling chrAig.put('369604101'/4.55) ---------- " + " @t=" + System.currentTimeMillis() + + " DirtyReadOffender calling chrAig.put('369604101'/3.85) " ); //sc.nextLine(); chrAig.setTransactionIsolation(ChronicleAcidIsolation.LOWEST_LATENCY); - bond.setCoupon(4.55); + bond.setCoupon(3.85); chrAig.put("369604101", bond); System.out.println( " @t=" + System.currentTimeMillis() + - " DirtyReadOffender sleeping 1 minute. ---------- " + " DirtyReadOffender sleeping 1 minute. " ); - Thread.sleep(60*1_000); - System.out.println( - " @t=" + System.currentTimeMillis() + - " DirtyReadOffender calling chrAig.rollback() ---------- " - ); - //sc.nextLine(); - //chrAig.commit(); - chrAig.rollback(); + Thread.sleep(60 * 1_000); System.out.println( " @t=" + System.currentTimeMillis() + - " DirtyReadOffender ROLLED BACK ---------- " + " DirtyReadOffender calling chrAig.rollback() " + ); + //sc.nextLine(); + //chrAig.commit(); Normally, app would be coded like this. demo the ROLLBACK + chrAig.rollback(); //forced to accommodate demo to Peter + System.out.println( + " @t=" + System.currentTimeMillis() + + " DirtyReadOffender ROLLED BACK " ); } catch (Exception throwables) { try { System.out.println( " @t=" + System.currentTimeMillis() + - " DirtyReadOffender calling chrAig.rollback ---------- " + " DirtyReadOffender calling chrAig.rollback " ); chrAig.rollback(); System.out.println( - " @t=" + System.currentTimeMillis() + - " DirtyReadOffender ROLLED BACK---------- " + " @t=" + System.currentTimeMillis() + + " DirtyReadOffender ROLLED BACK " ); } catch (SQLException e) { e.printStackTrace(); diff --git a/src/test/java/net/openhft/chronicle/map/fromdocs/acid/DirtyReadTolerance.java b/src/test/java/net/openhft/chronicle/map/fromdocs/acid/DirtyReadTolerance.java index 7ea9a091a..41aea4eaf 100644 --- a/src/test/java/net/openhft/chronicle/map/fromdocs/acid/DirtyReadTolerance.java +++ b/src/test/java/net/openhft/chronicle/map/fromdocs/acid/DirtyReadTolerance.java @@ -19,7 +19,7 @@ public class DirtyReadTolerance { public static void main(String args[]) throws Exception { - System.out.println("DirtyReadOffender,chrAig["+args[0]+"],DirtyReadVictim"); + System.out.println("DirtyReadOffender,chrAig["+args[0]+"]coupon=3.50,DirtyReadVictim"); String isoLevel = args[0]; ChronicleMap operand = 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 d2b85012c..b78ffedc2 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 @@ -35,14 +35,14 @@ public class DirtyReadVictim implements Runnable { Scanner sc= new Scanner(System.in); try { System.out.println( - " ,,---------- @t="+System.currentTimeMillis()+ + " ,,@t="+System.currentTimeMillis()+ " DirtyReadVictim sleeping 10 seconds" ); Thread.sleep(10_000); BondVOInterface bond = newNativeReference(BondVOInterface.class); chrAig.getCompositeChronicleMap().acquireUsing("369604101", bond); System.out.println( - " ,,---------- @t="+System.currentTimeMillis()+ + " ,,@t="+System.currentTimeMillis()+ " DirtyReadVictim calling chrAig.get('369604101')" ); //sc.nextLine(); @@ -52,25 +52,29 @@ public class DirtyReadVictim implements Runnable { bond = chrAig.get("369604101"); Double coupon = bond.getCoupon(); System.out.println( - " ,,---------- @t="+System.currentTimeMillis()+ - " DirtyReadVictim got() coupon="+coupon+" calling chrAig.commmit()" + " ,,@t="+System.currentTimeMillis()+ + " DirtyReadVictim got() coupon="+coupon+" " + ); + System.out.println( + " ,,@t="+System.currentTimeMillis()+ + " DirtyReadVictim calling chrAig.commmit()" ); //sc.nextLine(); chrAig.commit(); System.out.println( - " ,,---------- @t="+System.currentTimeMillis()+ + " ,,@t="+System.currentTimeMillis()+ " DirtyReadVictim COMMITTED" ); } catch (Exception throwables) { try { System.out.println( - " ,,---------- @t="+System.currentTimeMillis()+ + " ,,@t="+System.currentTimeMillis()+ " DirtyReadVictim calling chrAig.rollback()" ); //sc.nextLine(); chrAig.rollback(); System.out.println( - " ,,---------- @t="+System.currentTimeMillis()+ + " ,,@t="+System.currentTimeMillis()+ " DirtyReadVictim ROLLED BACK" ); } catch (SQLException e) { @@ -78,8 +82,6 @@ public class DirtyReadVictim implements Runnable { } throwables.printStackTrace(); } - - } }