This is an automated email from the ASF dual-hosted git repository. kturner pushed a commit to branch asf-site in repository https://gitbox.apache.org/repos/asf/fluo-website.git
The following commit(s) were added to refs/heads/asf-site by this push: new 103c1db Jekyll build from gh-pages:8590b7a 103c1db is described below commit 103c1db6facbbf7fae1d7af616cdf3afefdc9979 Author: Keith Turner <ktur...@apache.org> AuthorDate: Wed Mar 28 10:31:15 2018 -0400 Jekyll build from gh-pages:8590b7a Added read locks to tour (#156) --- feed.xml | 4 +- tour/application-configuration/index.html | 4 +- tour/architecture/index.html | 4 +- tour/basic-read-write/index.html | 4 +- tour/collision-code/index.html | 4 +- tour/collisions/index.html | 4 +- tour/data-model/index.html | 4 +- tour/data-pojos/index.html | 4 +- tour/exercise-1/index.html | 4 +- tour/index.html | 6 + tour/loader-executer/index.html | 4 +- tour/mem-self-ntfy-code/index.html | 4 +- tour/mem-self-ntfy/index.html | 4 +- tour/multi-get/index.html | 4 +- tour/observer_example/index.html | 4 +- tour/observers/index.html | 4 +- .../index.html | 122 +++++++++------------ tour/{write-skew => read-lock}/index.html | 52 +++++---- tour/recipes/index.html | 4 +- tour/row-locking/index.html | 4 +- tour/scanning-code/index.html | 4 +- tour/scanning/index.html | 8 +- tour/snapshot-isolation-code/index.html | 4 +- tour/snapshot-isolation/index.html | 4 +- tour/tx-logging/index.html | 4 +- tour/weak-code/index.html | 4 +- tour/weak-notifications/index.html | 4 +- tour/write-skew-code/index.html | 8 +- tour/write-skew/index.html | 7 +- tour/writing-code/index.html | 4 +- 30 files changed, 142 insertions(+), 157 deletions(-) diff --git a/feed.xml b/feed.xml index e42ccf5..8a4ac27 100644 --- a/feed.xml +++ b/feed.xml @@ -5,8 +5,8 @@ <description>Apache Fluo Website</description> <link>https://fluo.apache.org//</link> <atom:link href="https://fluo.apache.org//feed.xml" rel="self" type="application/rss+xml" /> - <pubDate>Fri, 23 Mar 2018 21:37:01 +0000</pubDate> - <lastBuildDate>Fri, 23 Mar 2018 21:37:01 +0000</lastBuildDate> + <pubDate>Wed, 28 Mar 2018 14:31:09 +0000</pubDate> + <lastBuildDate>Wed, 28 Mar 2018 14:31:09 +0000</lastBuildDate> <generator>Jekyll v3.6.2</generator> diff --git a/tour/application-configuration/index.html b/tour/application-configuration/index.html index a1b3811..9f8a940 100644 --- a/tour/application-configuration/index.html +++ b/tour/application-configuration/index.html @@ -112,7 +112,7 @@ <div id="tour-header"> <h2><a href="/tour/">Fluo Tour</a>: Application Configuration</h2> - <p class="text-muted">Tour page 23 of 26</p> + <p class="text-muted">Tour page 25 of 28</p> </div> <div id="tour-content"> <p>Fluo applications are distributed applications where code is running on many separate machines. @@ -261,7 +261,7 @@ if (e.keyCode == '39') { window.location = '/tour/mem-self-ntfy/'; } <a href="/tour/weak-code/"><</a> - 23 / 26 + 25 / 28 <a href="/tour/mem-self-ntfy/">></a> diff --git a/tour/architecture/index.html b/tour/architecture/index.html index 1a9a84a..d25a362 100644 --- a/tour/architecture/index.html +++ b/tour/architecture/index.html @@ -112,7 +112,7 @@ <div id="tour-header"> <h2><a href="/tour/">Fluo Tour</a>: Architecture</h2> - <p class="text-muted">Tour page 2 of 26</p> + <p class="text-muted">Tour page 2 of 28</p> </div> <div id="tour-content"> <p>An <a href="/docs/fluo/1.2/getting-started/design">overview</a> of the Fluo Architecture can be found in Fluo’s documentation.</p> @@ -139,7 +139,7 @@ if (e.keyCode == '39') { window.location = '/tour/writing-code/'; } <a href="/tour/data-model/"><</a> - 2 / 26 + 2 / 28 <a href="/tour/writing-code/">></a> diff --git a/tour/basic-read-write/index.html b/tour/basic-read-write/index.html index 28317fc..69accfa 100644 --- a/tour/basic-read-write/index.html +++ b/tour/basic-read-write/index.html @@ -112,7 +112,7 @@ <div id="tour-header"> <h2><a href="/tour/">Fluo Tour</a>: Read and Write Data</h2> - <p class="text-muted">Tour page 4 of 26</p> + <p class="text-muted">Tour page 4 of 28</p> </div> <div id="tour-content"> <p>The following shows Java code for writing and reading data using Fluo. In your local clone, modify @@ -172,7 +172,7 @@ if (e.keyCode == '39') { window.location = '/tour/data-pojos/'; } <a href="/tour/writing-code/"><</a> - 4 / 26 + 4 / 28 <a href="/tour/data-pojos/">></a> diff --git a/tour/collision-code/index.html b/tour/collision-code/index.html index a80db9c..44998ab 100644 --- a/tour/collision-code/index.html +++ b/tour/collision-code/index.html @@ -112,7 +112,7 @@ <div id="tour-header"> <h2><a href="/tour/">Fluo Tour</a>: Collision code</h2> - <p class="text-muted">Tour page 9 of 26</p> + <p class="text-muted">Tour page 9 of 28</p> </div> <div id="tour-content"> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kd">private</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">exercise</span><span class="o">(</span><span class="n">MiniFluo</span> <span class="n">mini</span><span class="o">,</span> <span class="n">FluoClient</span> <span class="n">client</span><span class="o">)</span> <span class="o">{</span> @@ -172,7 +172,7 @@ if (e.keyCode == '39') { window.location = '/tour/tx-logging/'; } <a href="/tour/collisions/"><</a> - 9 / 26 + 9 / 28 <a href="/tour/tx-logging/">></a> diff --git a/tour/collisions/index.html b/tour/collisions/index.html index 58e50a7..396b636 100644 --- a/tour/collisions/index.html +++ b/tour/collisions/index.html @@ -112,7 +112,7 @@ <div id="tour-header"> <h2><a href="/tour/">Fluo Tour</a>: Collisions</h2> - <p class="text-muted">Tour page 8 of 26</p> + <p class="text-muted">Tour page 8 of 28</p> </div> <div id="tour-content"> <p>When two transactions overlap and attempt to modify the same data, one of them @@ -152,7 +152,7 @@ if (e.keyCode == '39') { window.location = '/tour/collision-code/'; } <a href="/tour/snapshot-isolation-code/"><</a> - 8 / 26 + 8 / 28 <a href="/tour/collision-code/">></a> diff --git a/tour/data-model/index.html b/tour/data-model/index.html index a353594..311f6f8 100644 --- a/tour/data-model/index.html +++ b/tour/data-model/index.html @@ -112,7 +112,7 @@ <div id="tour-header"> <h2><a href="/tour/">Fluo Tour</a>: Data Model</h2> - <p class="text-muted">Tour page 1 of 26</p> + <p class="text-muted">Tour page 1 of 28</p> </div> <div id="tour-content"> <p>Fluo uses Accumulo’s data model which is based on the BigTable data model. @@ -167,7 +167,7 @@ if (e.keyCode == '39') { window.location = '/tour/architecture/'; } <h2> - 1 / 26 + 1 / 28 <a href="/tour/architecture/">></a> diff --git a/tour/data-pojos/index.html b/tour/data-pojos/index.html index 5a31058..1d2cb50 100644 --- a/tour/data-pojos/index.html +++ b/tour/data-pojos/index.html @@ -112,7 +112,7 @@ <div id="tour-header"> <h2><a href="/tour/">Fluo Tour</a>: Basic Data Types</h2> - <p class="text-muted">Tour page 5 of 26</p> + <p class="text-muted">Tour page 5 of 28</p> </div> <div id="tour-content"> <p>Fluo has a few simple POJOs that are used throughout the API. These classes @@ -149,7 +149,7 @@ if (e.keyCode == '39') { window.location = '/tour/snapshot-isolation/'; } <a href="/tour/basic-read-write/"><</a> - 5 / 26 + 5 / 28 <a href="/tour/snapshot-isolation/">></a> diff --git a/tour/exercise-1/index.html b/tour/exercise-1/index.html index b9f34dc..3fb6b80 100644 --- a/tour/exercise-1/index.html +++ b/tour/exercise-1/index.html @@ -112,7 +112,7 @@ <div id="tour-header"> <h2><a href="/tour/">Fluo Tour</a>: Word counts for unique documents exercise</h2> - <p class="text-muted">Tour page 19 of 26</p> + <p class="text-muted">Tour page 21 of 28</p> </div> <div id="tour-content"> <p>This exercise gives you an opportunity to use everything you have learned so @@ -754,7 +754,7 @@ if (e.keyCode == '39') { window.location = '/tour/row-locking/'; } <a href="/tour/observer_example/"><</a> - 19 / 26 + 21 / 28 <a href="/tour/row-locking/">></a> diff --git a/tour/index.html b/tour/index.html index 86689a8..603d838 100644 --- a/tour/index.html +++ b/tour/index.html @@ -174,6 +174,12 @@ thoughts, solutions, etc related to this tour can also be tweeted using the has <p><a href="/tour/write-skew-code/">Write Skew Code</a></p> </li> <li> + <p><a href="/tour/read-lock/">Read Locks</a></p> + </li> + <li> + <p><a href="/tour/read-lock-code/">Read Lock Code</a></p> + </li> + <li> <p><a href="/tour/scanning/">Scanning</a></p> </li> <li> diff --git a/tour/loader-executer/index.html b/tour/loader-executer/index.html index 0e512d9..eff2258 100644 --- a/tour/loader-executer/index.html +++ b/tour/loader-executer/index.html @@ -112,7 +112,7 @@ <div id="tour-header"> <h2><a href="/tour/">Fluo Tour</a>: Loader Executor</h2> - <p class="text-muted">Tour page 16 of 26</p> + <p class="text-muted">Tour page 18 of 28</p> </div> <div id="tour-content"> <p>Fluo provides a simple mechanism to help load data called the <a href="https://javadoc.io/page/org.apache.fluo/fluo-api/1.2.0/org/apache/fluo/api/client/LoaderExecutor.html">LoaderExecutor</a>. Loading data @@ -152,7 +152,7 @@ if (e.keyCode == '39') { window.location = '/tour/observers/'; } <a href="/tour/multi-get/"><</a> - 16 / 26 + 18 / 28 <a href="/tour/observers/">></a> diff --git a/tour/mem-self-ntfy-code/index.html b/tour/mem-self-ntfy-code/index.html index dc5790d..f06b581 100644 --- a/tour/mem-self-ntfy-code/index.html +++ b/tour/mem-self-ntfy-code/index.html @@ -112,7 +112,7 @@ <div id="tour-header"> <h2><a href="/tour/">Fluo Tour</a>: Memory limits and self notify code</h2> - <p class="text-muted">Tour page 25 of 26</p> + <p class="text-muted">Tour page 27 of 28</p> </div> <div id="tour-content"> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kd">static</span> <span class="n">Column</span> <span class="n">NC</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Column</span><span class="o">(</span><span class="s">"ntyf"</span><span class="o">,</span> <span class="s">"sum"</span><span class="o">);</span> @@ -247,7 +247,7 @@ if (e.keyCode == '39') { window.location = '/tour/recipes/'; } <a href="/tour/mem-self-ntfy/"><</a> - 25 / 26 + 27 / 28 <a href="/tour/recipes/">></a> diff --git a/tour/mem-self-ntfy/index.html b/tour/mem-self-ntfy/index.html index 9d2ac16..777e0af 100644 --- a/tour/mem-self-ntfy/index.html +++ b/tour/mem-self-ntfy/index.html @@ -112,7 +112,7 @@ <div id="tour-header"> <h2><a href="/tour/">Fluo Tour</a>: Memory limits and self notify</h2> - <p class="text-muted">Tour page 24 of 26</p> + <p class="text-muted">Tour page 26 of 28</p> </div> <div id="tour-content"> <p>All modifications made as part of a transaction must fit into memory because the sets and deletes @@ -157,7 +157,7 @@ if (e.keyCode == '39') { window.location = '/tour/mem-self-ntfy-code/'; } <a href="/tour/application-configuration/"><</a> - 24 / 26 + 26 / 28 <a href="/tour/mem-self-ntfy-code/">></a> diff --git a/tour/multi-get/index.html b/tour/multi-get/index.html index 73fca5d..b275205 100644 --- a/tour/multi-get/index.html +++ b/tour/multi-get/index.html @@ -112,7 +112,7 @@ <div id="tour-header"> <h2><a href="/tour/">Fluo Tour</a>: Fetching multiple cells</h2> - <p class="text-muted">Tour page 15 of 26</p> + <p class="text-muted">Tour page 17 of 28</p> </div> <div id="tour-content"> <p>Each call to get a row column results in a RPC to an Accumulo server. In the cases where there are @@ -268,7 +268,7 @@ if (e.keyCode == '39') { window.location = '/tour/loader-executer/'; } <a href="/tour/scanning-code/"><</a> - 15 / 26 + 17 / 28 <a href="/tour/loader-executer/">></a> diff --git a/tour/observer_example/index.html b/tour/observer_example/index.html index 7649453..47d64f4 100644 --- a/tour/observer_example/index.html +++ b/tour/observer_example/index.html @@ -112,7 +112,7 @@ <div id="tour-header"> <h2><a href="/tour/">Fluo Tour</a>: Observer Example</h2> - <p class="text-muted">Tour page 18 of 26</p> + <p class="text-muted">Tour page 20 of 28</p> </div> <div id="tour-content"> <p>The following code shows how to setup and trigger an observer. The observer is triggered when the @@ -217,7 +217,7 @@ if (e.keyCode == '39') { window.location = '/tour/exercise-1/'; } <a href="/tour/observers/"><</a> - 18 / 26 + 20 / 28 <a href="/tour/exercise-1/">></a> diff --git a/tour/observers/index.html b/tour/observers/index.html index cbc4e49..98edad3 100644 --- a/tour/observers/index.html +++ b/tour/observers/index.html @@ -112,7 +112,7 @@ <div id="tour-header"> <h2><a href="/tour/">Fluo Tour</a>: Observer Concepts</h2> - <p class="text-muted">Tour page 17 of 26</p> + <p class="text-muted">Tour page 19 of 28</p> </div> <div id="tour-content"> <p>Fluo supports incremental processing with Observers and Notifications. Notifications are persistent @@ -160,7 +160,7 @@ if (e.keyCode == '39') { window.location = '/tour/observer_example/'; } <a href="/tour/loader-executer/"><</a> - 17 / 26 + 19 / 28 <a href="/tour/observer_example/">></a> diff --git a/tour/observer_example/index.html b/tour/read-lock-code/index.html similarity index 51% copy from tour/observer_example/index.html copy to tour/read-lock-code/index.html index 7649453..d27e3de 100644 --- a/tour/observer_example/index.html +++ b/tour/read-lock-code/index.html @@ -8,10 +8,10 @@ <link href="https://maxcdn.bootstrapcdn.com/bootswatch/3.3.7/cosmo/bootstrap.min.css" rel="stylesheet" integrity="sha384-h21C2fcDk/eFsW9sC9h0dhokq5pDinLNklTKoxIZRUn3+hvmgQSffLLQ4G4l2eEr" crossorigin="anonymous"> <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous"> <link rel="stylesheet" href="/css/fluo.css"> - <link rel="canonical" href="https://fluo.apache.org//tour/observer_example/"> + <link rel="canonical" href="https://fluo.apache.org//tour/read-lock-code/"> <link rel="icon" type="image/png" href="/resources/favicon.png"> - <title>Observer Example | Apache Fluo</title> + <title>Read Lock Code | Apache Fluo</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> @@ -111,101 +111,81 @@ <div id="tour-header"> - <h2><a href="/tour/">Fluo Tour</a>: Observer Example</h2> - <p class="text-muted">Tour page 18 of 26</p> + <h2><a href="/tour/">Fluo Tour</a>: Read Lock Code</h2> + <p class="text-muted">Tour page 14 of 28</p> </div> <div id="tour-content"> - <p>The following code shows how to setup and trigger an observer. The observer is triggered when the -column <em>obs:data</em> is changed.</p> - -<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="n">Column</span> <span class="n">OBSERVED_COL</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Column</span><span class="o">(</span><span class="s">"obs"</span><span class="o">,</span> <span class="s">"data"</span><span class="o">);</span> - <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="n">Column</span> <span class="n">INVERT_COL</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Column</span><span class="o">(</span><span class="s">"inv"</span><span class="o">,</span> <span class="s">"data"</span><span class="o">);</span> - - <span class="c1">// This class is responsible for registering Observers for all observed columns.</span> - <span class="kd">public</span> <span class="kd">static</span> <span class="kd">class</span> <span class="nc">MyObserverProvider</span> <span class="kd">implements</span> <span class="n">ObserverProvider</span> <span class="o">{</span> - - <span class="nd">@Override</span> - <span class="kd">public</span> <span class="kt">void</span> <span class="nf">provide</span><span class="o">(</span><span class="n">Registry</span> <span class="n">obsRegistry</span><span class="o">,</span> <span class="n">Context</span> <span class="n">ctx</span><span class="o">)</span> <span class="o">{</span> - - <span class="c1">// Observer is a functional interface allowing Observers to be lambdas</span> - <span class="n">Observer</span> <span class="n">invObserver</span> <span class="o">=</span> <span class="o">(</span><span class="n">tx</span><span class="o">,</span> <span class="n">row</span><span class="o">,</span> <span class="n">col</span><span class="o">)</span> <span class="o">-></span> <span class="o">{</span> - <span class="n">Bytes</span> <span class="n">value</span> <span class="o">=</span> <span class="n">tx</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="n">row</span><span class="o">,</span> <span class="n">col</span><span class="o">);</span> - <span class="n">tx</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="n">value</span><span class="o">,</span> <span class="n">INVERT_COL</span><span class="o">,</span> <span class="n">row</span><span class="o">);</span> - <span class="o">};</span> - - <span class="c1">// Register an observer to process notifications for the column obs:data</span> - <span class="n">obsRegistry</span><span class="o">.</span><span class="na">forColumn</span><span class="o">(</span><span class="n">OBSERVED_COL</span><span class="o">,</span> <span class="n">NotificationType</span><span class="o">.</span><span class="na">STRONG</span><span class="o">).</span><span class="na">useObserver</span><span class="o">(</span><span class="n">invObserver</span><span class="o">);</span> - <span class="o">}</span> - - <span class="o">}</span> - - <span class="kd">private</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">preInit</span><span class="o">(</span><span class="n">FluoConfiguration</span> <span class="n">fluoConfig</span><span class="o">)</span> <span class="o">{</span> - <span class="c1">// Configure ObserverProvider before initialization. Workers will instantiate this class and use</span> - <span class="c1">// it to create Observers.</span> - <span class="n">fluoConfig</span><span class="o">.</span><span class="na">setObserverProvider</span><span class="o">(</span><span class="n">MyObserverProvider</span><span class="o">.</span><span class="na">class</span><span class="o">);</span> - <span class="o">}</span> + <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kd">private</span> <span class="kd">static</span> <span class="kd">final</span> <span class="n">Column</span> <span class="n">WEIGHT_COL</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Column</span><span class="o">(</span><span class="s">"stat"</span><span class="o">,</span> <span class="s">"weight"</span><span class="o">);</span> <span class="kd">private</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">exercise</span><span class="o">(</span><span class="n">MiniFluo</span> <span class="n">mini</span><span class="o">,</span> <span class="n">FluoClient</span> <span class="n">client</span><span class="o">)</span> <span class="o">{</span> <span class="k">try</span> <span class="o">(</span><span class="n">Transaction</span> <span class="n">tx1</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="na">newTransaction</span><span class="o">())</span> <span class="o">{</span> - <span class="n">tx1</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="s">"kerbalnaut0001"</span><span class="o">,</span> <span class="n">OBSERVED_COL</span><span class="o">,</span> <span class="s">"Jebediah"</span><span class="o">);</span> + <span class="n">tx1</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="s">"kerbalnaut0001"</span><span class="o">,</span> <span class="n">WEIGHT_COL</span><span class="o">,</span> <span class="s">"90"</span><span class="o">);</span> + <span class="n">tx1</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="s">"kerbalnaut0002"</span><span class="o">,</span> <span class="n">WEIGHT_COL</span><span class="o">,</span> <span class="s">"70"</span><span class="o">);</span> + <span class="n">tx1</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="s">"kerbalnaut0003"</span><span class="o">,</span> <span class="n">WEIGHT_COL</span><span class="o">,</span> <span class="s">"80"</span><span class="o">);</span> <span class="n">tx1</span><span class="o">.</span><span class="na">commit</span><span class="o">();</span> <span class="o">}</span> - <span class="k">try</span> <span class="o">(</span><span class="n">Transaction</span> <span class="n">tx2</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="na">newTransaction</span><span class="o">())</span> <span class="o">{</span> - <span class="n">tx2</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="s">"kerbalnaut0002"</span><span class="o">,</span> <span class="n">OBSERVED_COL</span><span class="o">,</span> <span class="s">"Bill"</span><span class="o">);</span> - <span class="n">tx2</span><span class="o">.</span><span class="na">commit</span><span class="o">();</span> + <span class="k">try</span> <span class="o">(</span><span class="n">Transaction</span> <span class="n">tx2</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="na">newTransaction</span><span class="o">();</span> + <span class="n">Transaction</span> <span class="n">tx3</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="na">newTransaction</span><span class="o">();</span> + <span class="n">Transaction</span> <span class="n">tx4</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="na">newTransaction</span><span class="o">())</span> + <span class="o">{</span> + <span class="kt">int</span> <span class="n">f1w1</span> <span class="o">=</span> <span class="n">Integer</span><span class="o">.</span><span class="na">parseInt</span><span class="o">(</span><span class="n">tx2</span><span class="o">.</span><span class="na">withReadLock</span><span class="o">().</span><span class="na">gets</span><span class="o">(</span><span class="s">"kerbalnaut0001"</span><span class="o">,</span> <span class="n">WEIGHT_COL</span><span class="o">));</span> + <span class="kt">int</span> <span class="n">f1w2</span> <span class="o">=</span> <span class="n">Integer</span><span class="o">.</span><span class="na">parseInt</span><span class="o">(</span><span class="n">tx2</span><span class="o">.</span><span class="na">withReadLock</span><span class="o">().</span><span class="na">gets</span><span class="o">(</span><span class="s">"kerbalnaut0003"</span><span class="o">,</span> <span class="n">WEIGHT_COL</span><span class="o">));</span> + <span class="n">tx2</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="s">"flight0001"</span><span class="o">,</span> <span class="n">WEIGHT_COL</span><span class="o">,</span> <span class="n">f1w1</span> <span class="o">+</span> <span class="n">f1w2</span> <span class="o">+</span> <span class="s">""</span><span class="o">);</span> + + <span class="kt">int</span> <span class="n">f2w1</span> <span class="o">=</span> <span class="n">Integer</span><span class="o">.</span><span class="na">parseInt</span><span class="o">(</span><span class="n">tx3</span><span class="o">.</span><span class="na">withReadLock</span><span class="o">().</span><span class="na">gets</span><span class="o">(</span><span class="s">"kerbalnaut0001"</span><span class="o">,</span> <span class="n">WEIGHT_COL</span><span class="o">));</span> + <span class="kt">int</span> <span class="n">f2w2</span> <span class="o">=</span> <span class="n">Integer</span><span class="o">.</span><span class="na">parseInt</span><span class="o">(</span><span class="n">tx3</span><span class="o">.</span><span class="na">withReadLock</span><span class="o">().</span><span class="na">gets</span><span class="o">(</span><span class="s">"kerbalnaut0002"</span><span class="o">,</span> <span class="n">WEIGHT_COL</span><span class="o">));</span> + <span class="n">tx3</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="s">"flight0002"</span><span class="o">,</span> <span class="n">WEIGHT_COL</span><span class="o">,</span> <span class="n">f2w1</span> <span class="o">+</span> <span class="n">f2w2</span> <span class="o">+</span> <span class="s">""</span><span class="o">);</span> + + <span class="n">tx4</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="s">"kerbalnaut0001"</span><span class="o">,</span> <span class="n">WEIGHT_COL</span><span class="o">,</span> <span class="s">"95"</span><span class="o">);</span> + + <span class="k">for</span><span class="o">(</span><span class="n">Transaction</span> <span class="n">ctx</span> <span class="o">:</span> <span class="n">Arrays</span><span class="o">.</span><span class="na">asList</span><span class="o">(</span><span class="n">tx2</span><span class="o">,</span><span class="n">tx3</span><span class="o">,</span><span class="n">tx4</span><span class="o">))</span> <span class="o">{</span> + <span class="k">try</span> <span class="o">{</span> + <span class="n">ctx</span><span class="o">.</span><span class="na">commit</span><span class="o">();</span> + <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="n">CommitException</span> <span class="n">ce</span><span class="o">)</span> <span class="o">{</span> + <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"commit failed: "</span><span class="o">+</span><span class="n">ce</span><span class="o">.</span><span class="na">getMessage</span><span class="o">());</span> + <span class="o">}</span> + <span class="o">}</span> <span class="o">}</span> - <span class="n">mini</span><span class="o">.</span><span class="na">waitForObservers</span><span class="o">();</span> - - <span class="k">try</span> <span class="o">(</span><span class="n">Snapshot</span> <span class="n">snap</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="na">newSnapshot</span><span class="o">())</span> <span class="o">{</span> + <span class="k">try</span><span class="o">(</span><span class="n">Snapshot</span> <span class="n">snap</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="na">newSnapshot</span><span class="o">())</span> <span class="o">{</span> <span class="n">snap</span><span class="o">.</span><span class="na">scanner</span><span class="o">().</span><span class="na">build</span><span class="o">().</span><span class="na">forEach</span><span class="o">(</span><span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">::</span><span class="n">println</span><span class="o">);</span> <span class="o">}</span> <span class="o">}</span> </code></pre></div></div> -<p>The code above prints :</p> +<p>Output :</p> -<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Bill inv data kerbalnaut0002 -Jebediah inv data kerbalnaut0001 -kerbalnaut0001 obs data Jebediah -kerbalnaut0002 obs data Bill +<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>commit failed: Collisions(1):kerbalnaut0001 stat weight +flight0001 stat weight 170 +flight0002 stat weight 160 +kerbalnaut0001 stat weight 90 +kerbalnaut0002 stat weight 70 +kerbalnaut0003 stat weight 80 </code></pre></div></div> -<p>The following events happen when this code is run.</p> - -<ul> - <li><em>tx1</em> modifies <em>kerbalnaut0001:obs:data</em> causing <em>MyObserver</em> to run later on that row+column.</li> - <li><em>tx2</em> modifies <em>kerbalnaut0002:obs:data</em> causing <em>MyObserver</em> to run later on that row+column.</li> - <li>Later <em>MyObserver</em> is run and passed row+column <em>kerbalnaut0001:obs:data</em></li> - <li>Later <em>MyObserver</em> is run and passed row+column <em>kerbalnaut0002:obs:data</em></li> -</ul> +<p>Output for commit order <code class="highlighter-rouge">Arrays.asList(tx4,tx2,tx3)</code> :</p> -<p>Observers are run in the background by Fluo threads. Fluo also creates the -transaction passed to an Observer and commits it. The transaction does not -need to call commit and can not, the TransactionBase type passed to an Observer -does not have a commit method. The framework handles committing because it -retries in case of a commit exception.</p> - -<p>Since observers are run in the background, you never know when they will run. -For testing purposes MiniFluo provides the waitForObservers() method that is -called above. This method waits for all notifications to be processed by -observers.</p> - -<p>There is no stand alone exercise for the Observer. Hands on experience with it can be obtained by -completing the <a href="/tour/exercise-1/">word count exercise</a> which is the next step in the tour.</p> +<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>commit failed: Collisions(1):kerbalnaut0001 stat weight +commit failed: Collisions(1):kerbalnaut0001 stat weight +kerbalnaut0001 stat weight 95 +kerbalnaut0002 stat weight 70 +kerbalnaut0003 stat weight 80 +</code></pre></div></div> +<p>With this commit order <em>tx4</em> gets a write lock on <em>kerbalnaut0001:stat:weight</em> +which prevents <em>tx2</em> and <em>tx3</em> from getting read locks.</p> </div> <script> document.body.onkeyup = function(e){ -if (e.keyCode == '37') { window.location = '/tour/observers/'; } +if (e.keyCode == '37') { window.location = '/tour/read-lock/'; } -if (e.keyCode == '39') { window.location = '/tour/exercise-1/'; } +if (e.keyCode == '39') { window.location = '/tour/scanning/'; } }; </script> @@ -214,12 +194,12 @@ if (e.keyCode == '39') { window.location = '/tour/exercise-1/'; } <h2> - <a href="/tour/observers/"><</a> + <a href="/tour/read-lock/"><</a> - 18 / 26 + 14 / 28 - <a href="/tour/exercise-1/">></a> + <a href="/tour/scanning/">></a> </h2> </div> diff --git a/tour/write-skew/index.html b/tour/read-lock/index.html similarity index 76% copy from tour/write-skew/index.html copy to tour/read-lock/index.html index 25a1862..4c3e93e 100644 --- a/tour/write-skew/index.html +++ b/tour/read-lock/index.html @@ -8,10 +8,10 @@ <link href="https://maxcdn.bootstrapcdn.com/bootswatch/3.3.7/cosmo/bootstrap.min.css" rel="stylesheet" integrity="sha384-h21C2fcDk/eFsW9sC9h0dhokq5pDinLNklTKoxIZRUn3+hvmgQSffLLQ4G4l2eEr" crossorigin="anonymous"> <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous"> <link rel="stylesheet" href="/css/fluo.css"> - <link rel="canonical" href="https://fluo.apache.org//tour/write-skew/"> + <link rel="canonical" href="https://fluo.apache.org//tour/read-lock/"> <link rel="icon" type="image/png" href="/resources/favicon.png"> - <title>Write Skew | Apache Fluo</title> + <title>Read Locks | Apache Fluo</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> @@ -111,49 +111,47 @@ <div id="tour-header"> - <h2><a href="/tour/">Fluo Tour</a>: Write Skew</h2> - <p class="text-muted">Tour page 11 of 26</p> + <h2><a href="/tour/">Fluo Tour</a>: Read Locks</h2> + <p class="text-muted">Tour page 13 of 28</p> </div> <div id="tour-content"> - <p>The page on collisions showed that if two transactions overlap and write the same data then one will -fail. However, in the case where two transactions overlap and one reads data that another is writing -both can succeed. This behavior is called write skew.</p> - -<p>The example below shows write skew. In the example, <em>n0</em> is a node in a tree with two children <em>n01</em> -and <em>n02</em>. In <em>tx2</em>, the sum of <em>n0</em> is set to the sum of its children. However, <em>tx2</em> misses the -concurrent update from <em>tx3</em>. Both <em>tx2</em> and <em>tx3</em> will commit successfully since they write to -different keys.</p> + <p>By default, reads do not acquire a lock which makes normal reads faster. +Read locks can optionally be acquired via the <a href="https://javadoc.io/page/org.apache.fluo/fluo-api/1.2.0/org/apache/fluo/api/client/TransactionBase.html#withReadLock--">withReadLock</a> method. For +example, if <code class="highlighter-rouge">tx</code> is a transaction then <code class="highlighter-rouge">tx.withReadLock().get(row,col)</code> +reads with a lock.</p> <ul> <li><strong>Create transaction</strong> <em>tx1</em></li> - <li><strong>Using</strong> <em>tx1</em> <strong>set</strong> <em>n0:data:sum</em> <strong>to</strong> <em>0</em></li> - <li><strong>Using</strong> <em>tx1</em> <strong>set</strong> <em>n01:data:sum</em> <strong>to</strong> <em>1</em></li> - <li><strong>Using</strong> <em>tx1</em> <strong>set</strong> <em>n02:data:sum</em> <strong>to</strong> <em>2</em></li> + <li><strong>Using</strong> <em>tx1</em> <strong>set</strong> <em>kerbalnaut0001:stat:weight</em> <strong>to</strong> <em>90</em></li> + <li><strong>Using</strong> <em>tx1</em> <strong>set</strong> <em>kerbalnaut0002:stat:weight</em> <strong>to</strong> <em>70</em></li> + <li><strong>Using</strong> <em>tx1</em> <strong>set</strong> <em>kerbalnaut0003:stat:weight</em> <strong>to</strong> <em>80</em></li> <li><strong>Commit</strong> <em>tx1</em></li> <li><strong>Create transaction</strong> <em>tx2</em></li> <li><strong>Create transaction</strong> <em>tx3</em></li> - <li><strong>Using</strong> <em>tx2</em> <strong>set</strong> <em>n0:data:sum</em> <strong>to the value of</strong> <em>n01:data:sum</em> <strong>plus</strong> <em>n02:data:sum</em></li> - <li><strong>Using</strong> <em>tx3</em> <strong>set</strong> <em>n01:data:sum</em> <strong>to</strong> <em>5</em></li> + <li><strong>Create transaction</strong> <em>tx4</em></li> + <li><strong>Using</strong> <em>tx2</em> <strong>set</strong> <em>flight0001:stat:weight</em> <strong>to the read locked values of</strong> <em>kerbalnaut0001:stat:weight</em> <strong>plus</strong> <em>kerbalnaut0003:stat:weight</em></li> + <li><strong>Using</strong> <em>tx3</em> <strong>set</strong> <em>flight0002:stat:weight</em> <strong>to the read locked values of</strong> <em>kerbalnaut0001:stat:weight</em> <strong>plus</strong> <em>kerbalnaut0002:stat:weight</em></li> + <li><strong>Using</strong> <em>tx4</em> <strong>set</strong> <em>kerbalnaut0001:stat:weight</em> <strong>to</strong> <em>95</em></li> <li><strong>Commit</strong> <em>tx2</em></li> <li><strong>Commit</strong> <em>tx3</em></li> - <li><strong>Create snapshot and print</strong> <em>n0:data:sum</em>, <em>n01:data:sum</em>, <strong>and</strong> <em>n02:data:sum</em></li> + <li><strong>Commit</strong> <em>tx4</em></li> </ul> -<p>The changes made by <em>tx3</em> will not be seen by <em>tx2</em>. This behavior is OK if the update made by <em>tx3</em> -triggers a later update of <em>n0:data:sum</em>. Later pages in the tour will show that Observers can work -this way, so that eventually the changes made by <em>tx3</em> are incorporated. The <a href="/tour/weak-notifications/">Weak Notification -Exercise</a> later in the tour shows an example of this.</p> +<p>Both <em>tx2</em> and <em>tx3</em> get a read lock on <em>kerbalnaut0001:stat:weight</em> without +interfering with each other. The read locks prevent <em>tx4</em> from committing. +Try reordering the commits for <em>tx2</em>, <em>tx3</em>, and <em>tx4</em>.</p> + </div> <script> document.body.onkeyup = function(e){ -if (e.keyCode == '37') { window.location = '/tour/tx-logging/'; } +if (e.keyCode == '37') { window.location = '/tour/write-skew-code/'; } -if (e.keyCode == '39') { window.location = '/tour/write-skew-code/'; } +if (e.keyCode == '39') { window.location = '/tour/read-lock-code/'; } }; </script> @@ -162,12 +160,12 @@ if (e.keyCode == '39') { window.location = '/tour/write-skew-code/'; } <h2> - <a href="/tour/tx-logging/"><</a> + <a href="/tour/write-skew-code/"><</a> - 11 / 26 + 13 / 28 - <a href="/tour/write-skew-code/">></a> + <a href="/tour/read-lock-code/">></a> </h2> </div> diff --git a/tour/recipes/index.html b/tour/recipes/index.html index 22264da..a970d6e 100644 --- a/tour/recipes/index.html +++ b/tour/recipes/index.html @@ -112,7 +112,7 @@ <div id="tour-header"> <h2><a href="/tour/">Fluo Tour</a>: Fluo Recipes</h2> - <p class="text-muted">Tour page 26 of 26</p> + <p class="text-muted">Tour page 28 of 28</p> </div> <div id="tour-content"> <p>Coming soon, a tour of <a href="https://github.com/apache/fluo-recipes">Fluo Recipes</a>.</p> @@ -137,7 +137,7 @@ if (e.keyCode == '37') { window.location = '/tour/mem-self-ntfy-code/'; } <a href="/tour/mem-self-ntfy-code/"><</a> - 26 / 26 + 28 / 28 </h2> </div> diff --git a/tour/row-locking/index.html b/tour/row-locking/index.html index 0f4c4e0..b0dad38 100644 --- a/tour/row-locking/index.html +++ b/tour/row-locking/index.html @@ -112,7 +112,7 @@ <div id="tour-header"> <h2><a href="/tour/">Fluo Tour</a>: Row Locking</h2> - <p class="text-muted">Tour page 20 of 26</p> + <p class="text-muted">Tour page 22 of 28</p> </div> <div id="tour-content"> <p>Fluo relies on Accumulo’s conditional mutations to implement cross node @@ -233,7 +233,7 @@ if (e.keyCode == '39') { window.location = '/tour/weak-notifications/'; } <a href="/tour/exercise-1/"><</a> - 20 / 26 + 22 / 28 <a href="/tour/weak-notifications/">></a> diff --git a/tour/scanning-code/index.html b/tour/scanning-code/index.html index 195435e..681a57d 100644 --- a/tour/scanning-code/index.html +++ b/tour/scanning-code/index.html @@ -112,7 +112,7 @@ <div id="tour-header"> <h2><a href="/tour/">Fluo Tour</a>: Scanning Code</h2> - <p class="text-muted">Tour page 14 of 26</p> + <p class="text-muted">Tour page 16 of 28</p> </div> <div id="tour-content"> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kd">private</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">exercise</span><span class="o">(</span><span class="n">MiniFluo</span> <span class="n">mini</span><span class="o">,</span> <span class="n">FluoClient</span> <span class="n">client</span><span class="o">)</span> <span class="o">{</span> @@ -205,7 +205,7 @@ if (e.keyCode == '39') { window.location = '/tour/multi-get/'; } <a href="/tour/scanning/"><</a> - 14 / 26 + 16 / 28 <a href="/tour/multi-get/">></a> diff --git a/tour/scanning/index.html b/tour/scanning/index.html index a8cacbb..9778f55 100644 --- a/tour/scanning/index.html +++ b/tour/scanning/index.html @@ -112,7 +112,7 @@ <div id="tour-header"> <h2><a href="/tour/">Fluo Tour</a>: Scanning</h2> - <p class="text-muted">Tour page 13 of 26</p> + <p class="text-muted">Tour page 15 of 28</p> </div> <div id="tour-content"> <p>In some situations, you may want to read a range of data instead of specific rows and columns. For @@ -153,7 +153,7 @@ change data after <em>s1</em> is created but before the scans happen.</p> <script> document.body.onkeyup = function(e){ -if (e.keyCode == '37') { window.location = '/tour/write-skew-code/'; } +if (e.keyCode == '37') { window.location = '/tour/read-lock-code/'; } @@ -166,10 +166,10 @@ if (e.keyCode == '39') { window.location = '/tour/scanning-code/'; } <h2> - <a href="/tour/write-skew-code/"><</a> + <a href="/tour/read-lock-code/"><</a> - 13 / 26 + 15 / 28 <a href="/tour/scanning-code/">></a> diff --git a/tour/snapshot-isolation-code/index.html b/tour/snapshot-isolation-code/index.html index 0d38e85..7f8efa4 100644 --- a/tour/snapshot-isolation-code/index.html +++ b/tour/snapshot-isolation-code/index.html @@ -112,7 +112,7 @@ <div id="tour-header"> <h2><a href="/tour/">Fluo Tour</a>: Snapshot Isolation Code</h2> - <p class="text-muted">Tour page 7 of 26</p> + <p class="text-muted">Tour page 7 of 28</p> </div> <div id="tour-content"> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kd">private</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">exercise</span><span class="o">(</span><span class="n">MiniFluo</span> <span class="n">mini</span><span class="o">,</span> <span class="n">FluoClient</span> <span class="n">client</span><span class="o">)</span> <span class="o">{</span> @@ -171,7 +171,7 @@ if (e.keyCode == '39') { window.location = '/tour/collisions/'; } <a href="/tour/snapshot-isolation/"><</a> - 7 / 26 + 7 / 28 <a href="/tour/collisions/">></a> diff --git a/tour/snapshot-isolation/index.html b/tour/snapshot-isolation/index.html index bc432b8..4979d44 100644 --- a/tour/snapshot-isolation/index.html +++ b/tour/snapshot-isolation/index.html @@ -112,7 +112,7 @@ <div id="tour-header"> <h2><a href="/tour/">Fluo Tour</a>: Snapshot Isolation</h2> - <p class="text-muted">Tour page 6 of 26</p> + <p class="text-muted">Tour page 6 of 28</p> </div> <div id="tour-content"> <p>Fluo provides Snapshot isolation. This means that a Transaction or Snapshot can only see data @@ -154,7 +154,7 @@ if (e.keyCode == '39') { window.location = '/tour/snapshot-isolation-code/'; } <a href="/tour/data-pojos/"><</a> - 6 / 26 + 6 / 28 <a href="/tour/snapshot-isolation-code/">></a> diff --git a/tour/tx-logging/index.html b/tour/tx-logging/index.html index 7d5ba5f..0b2e7c7 100644 --- a/tour/tx-logging/index.html +++ b/tour/tx-logging/index.html @@ -112,7 +112,7 @@ <div id="tour-header"> <h2><a href="/tour/">Fluo Tour</a>: Transaction Logging</h2> - <p class="text-muted">Tour page 10 of 26</p> + <p class="text-muted">Tour page 10 of 28</p> </div> <div id="tour-content"> <p>Fluo can produce detailed logs about transactions if configured to do so. @@ -174,7 +174,7 @@ if (e.keyCode == '39') { window.location = '/tour/write-skew/'; } <a href="/tour/collision-code/"><</a> - 10 / 26 + 10 / 28 <a href="/tour/write-skew/">></a> diff --git a/tour/weak-code/index.html b/tour/weak-code/index.html index 4869ebe..514c74e 100644 --- a/tour/weak-code/index.html +++ b/tour/weak-code/index.html @@ -112,7 +112,7 @@ <div id="tour-header"> <h2><a href="/tour/">Fluo Tour</a>: Weak Notification Code</h2> - <p class="text-muted">Tour page 22 of 26</p> + <p class="text-muted">Tour page 24 of 28</p> </div> <div id="tour-content"> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kd">static</span> <span class="n">Column</span> <span class="n">NC</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Column</span><span class="o">(</span><span class="s">"ntyf"</span><span class="o">,</span> <span class="s">"sum"</span><span class="o">);</span> @@ -204,7 +204,7 @@ if (e.keyCode == '39') { window.location = '/tour/application-configuration/'; } <a href="/tour/weak-notifications/"><</a> - 22 / 26 + 24 / 28 <a href="/tour/application-configuration/">></a> diff --git a/tour/weak-notifications/index.html b/tour/weak-notifications/index.html index e965ee3..4093cfa 100644 --- a/tour/weak-notifications/index.html +++ b/tour/weak-notifications/index.html @@ -112,7 +112,7 @@ <div id="tour-header"> <h2><a href="/tour/">Fluo Tour</a>: Weak Notification Exercise</h2> - <p class="text-muted">Tour page 21 of 26</p> + <p class="text-muted">Tour page 23 of 28</p> </div> <div id="tour-content"> <p>This exercise will use weak notification to update a shared counter. In the example, many threads @@ -163,7 +163,7 @@ if (e.keyCode == '39') { window.location = '/tour/weak-code/'; } <a href="/tour/row-locking/"><</a> - 21 / 26 + 23 / 28 <a href="/tour/weak-code/">></a> diff --git a/tour/write-skew-code/index.html b/tour/write-skew-code/index.html index 024acdc..0f61401 100644 --- a/tour/write-skew-code/index.html +++ b/tour/write-skew-code/index.html @@ -112,7 +112,7 @@ <div id="tour-header"> <h2><a href="/tour/">Fluo Tour</a>: Write Skew Code</h2> - <p class="text-muted">Tour page 12 of 26</p> + <p class="text-muted">Tour page 12 of 28</p> </div> <div id="tour-content"> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kd">private</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">exercise</span><span class="o">(</span><span class="n">MiniFluo</span> <span class="n">mini</span><span class="o">,</span> <span class="n">FluoClient</span> <span class="n">client</span><span class="o">)</span> <span class="o">{</span> @@ -163,7 +163,7 @@ if (e.keyCode == '37') { window.location = '/tour/write-skew/'; } -if (e.keyCode == '39') { window.location = '/tour/scanning/'; } +if (e.keyCode == '39') { window.location = '/tour/read-lock/'; } }; </script> @@ -175,9 +175,9 @@ if (e.keyCode == '39') { window.location = '/tour/scanning/'; } <a href="/tour/write-skew/"><</a> - 12 / 26 + 12 / 28 - <a href="/tour/scanning/">></a> + <a href="/tour/read-lock/">></a> </h2> </div> diff --git a/tour/write-skew/index.html b/tour/write-skew/index.html index 25a1862..3fd1400 100644 --- a/tour/write-skew/index.html +++ b/tour/write-skew/index.html @@ -112,7 +112,7 @@ <div id="tour-header"> <h2><a href="/tour/">Fluo Tour</a>: Write Skew</h2> - <p class="text-muted">Tour page 11 of 26</p> + <p class="text-muted">Tour page 11 of 28</p> </div> <div id="tour-content"> <p>The page on collisions showed that if two transactions overlap and write the same data then one will @@ -142,7 +142,8 @@ different keys.</p> <p>The changes made by <em>tx3</em> will not be seen by <em>tx2</em>. This behavior is OK if the update made by <em>tx3</em> triggers a later update of <em>n0:data:sum</em>. Later pages in the tour will show that Observers can work this way, so that eventually the changes made by <em>tx3</em> are incorporated. The <a href="/tour/weak-notifications/">Weak Notification -Exercise</a> later in the tour shows an example of this.</p> +Exercise</a> later in the tour shows an example of this. Another strategy +for dealing with write skew is <a href="/tour/read-lock/">read locks</a>.</p> </div> @@ -165,7 +166,7 @@ if (e.keyCode == '39') { window.location = '/tour/write-skew-code/'; } <a href="/tour/tx-logging/"><</a> - 11 / 26 + 11 / 28 <a href="/tour/write-skew-code/">></a> diff --git a/tour/writing-code/index.html b/tour/writing-code/index.html index bd07768..af8f5b0 100644 --- a/tour/writing-code/index.html +++ b/tour/writing-code/index.html @@ -112,7 +112,7 @@ <div id="tour-header"> <h2><a href="/tour/">Fluo Tour</a>: Writing and Running Fluo code</h2> - <p class="text-muted">Tour page 3 of 26</p> + <p class="text-muted">Tour page 3 of 28</p> </div> <div id="tour-content"> <p>Following the Fluo tour will require writing code that uses Fluo’s API. There is a git repository @@ -155,7 +155,7 @@ if (e.keyCode == '39') { window.location = '/tour/basic-read-write/'; } <a href="/tour/architecture/"><</a> - 3 / 26 + 3 / 28 <a href="/tour/basic-read-write/">></a> -- To stop receiving notification emails like this one, please contact ktur...@apache.org.