blob: 5ede52caebf9e2d75ccc6d47de096ea86fda4d58 [file] [log] [blame]
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd";>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<html>
<head>
<link rel="shortcut icon" href="http://aries.apache.org/images/favicon.ico"></link>
<link type="text/css" rel="stylesheet" href="http://aries.apache.org/resources/site.css"></link>
</script><script src="http://aries.apache.org/resources/menus.js" language="javascript" type="text/javascript"></script>
<meta name="keywords" content="..."/>
<meta name="description" content="..." />
<title>
Apache Aries - Using the Coordinator to optimise Transactions
</title>
</head>
<body onload="SetMenu()">
<table width="100%" cellpadding="0" cellspacing="0">
<tr width="100%">
<td id="cell-0-0" colspan="2">&nbsp;</td>
<td id="cell-0-1">&nbsp;</td>
<td id="cell-0-2" colspan="2">&nbsp;</td>
</tr>
<tr width="100%">
<td id="cell-1-0">&nbsp;</td>
<td id="cell-1-1">&nbsp;</td>
<td id="cell-1-2">
<div style="padding: 5px;">
<div id="banner">
<!-- Banner -->
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td align="left" class="topbardiv" nowrap="">
<a href="http://aries.apache.org/" title="Apache Aries"> <img border="0" src="http://aries.apache.org/images/Arieslogo_Horizontal.gif"> </a>
</td>
<td align="right" nowrap="">
<a href="http://www.apache.org/" title="The Apache Software Foundation"> <img border="0" src="http://aries.apache.org/images/apache_feather.png"> </a>
</td>
</tr>
</table>
<!-- Banner -->
</div>
</div>
<div id="top-menu">
<table border="0" cellpadding="1" cellspacing="0" width="100%">
<tr>
<td>
<div align="left">
<!-- Breadcrumbs -->
<!-- Breadcrumbs -->
</div>
</td>
<td>
<div align="right">
<!-- Quicklinks -->
<DIV style="padding: 5px 5px 0px 25px;">
<FORM action="http://www.google.com/search" method="get" style="font-size: 10px;">
<A href="http://www.apache.org/licenses/LICENSE-2.0.html" class="external-link" rel="nofollow">License</A>
<INPUT name="ie" type="hidden" value="UTF-8"></INPUT>
<INPUT name="oe" type="hidden" value="UTF-8"></INPUT>
<INPUT maxlength="255" name="q" size="15" type="text" value></INPUT>
<INPUT name="btnG" type="submit" value="Search"></INPUT>
<INPUT name="domains" type="hidden" value="aries.apache.org"></INPUT>
<INPUT name="sitesearch" type="hidden" value="aries.apache.org"></INPUT>
</FORM>
</DIV>
<!-- Quicklinks -->
</div>
</td>
</tr>
</table>
</div>
</td>
<td id="cell-1-3">&nbsp;</td>
<td id="cell-1-4">&nbsp;</td>
</tr>
<tr width="100%">
<td id="cell-2-0" colspan="2">&nbsp;</td>
<td id="cell-2-1">
<table>
<tr height="100%" valign="top">
<td height="100%">
<div id="wrapper-menu-page-right">
<div id="wrapper-menu-page-top">
<div id="wrapper-menu-page-bottom">
<div id="menu-page">
<!-- NavigationBar -->
<style type="text/css">
/* The following code is added by mdx_elementid.py
It was originally lifted from http://subversion.apache.org/style/site.css */
/*
* Hide class="elementid-permalink", except when an enclosing heading
* has the :hover property.
*/
.headerlink, .elementid-permalink {
visibility: hidden;
}
h2:hover > .headerlink, h3:hover > .headerlink, h1:hover > .headerlink, h6:hover > .headerlink, h4:hover > .headerlink, h5:hover > .headerlink, dt:hover > .elementid-permalink { visibility: visible }</style>
<div onclick="SwitchMenu('documentation')" id="documentationTitle" class="menutitle">Documentation</div>
<div id="documentation" class="menuitemgroup">
<div class="menuitem">
<a href="/documentation/integrators-guide.html">Integrators Guide</a>
</div>
<div class="menuitem">
<a href="/documentation/articles.html">Articles</a>
</div>
<div class="menuitem">
<a href="https://svn.apache.org/repos/asf/aries/slides/">Slides</a>
</div>
<div class="menuitem">
<a href="/documentation/tutorials.html">Tutorials</a>
</div>
<div class="menuitem">
<a href="/documentation/tools.html">Tools</a>
</div>
</div>
<div onclick="SwitchMenu('modules')" id="modulesTitle" class="menutitle">Modules</div>
<div id="modules" class="menuitemgroup">
<div class="menuitem">
<a href="/modules/samples.html">Samples</a>
</div>
<div class="menuitem">
<a href="/modules/async-svcs.html">Asynchronous Services</a>
</div>
<div class="menuitem">
<a href="/modules/blueprint.html">Blueprint</a>
</div>
<div class="menuitem">
<a href="/modules/blueprint-maven-plugin.html">Blueprint-maven-plugin</a>
</div>
<div class="menuitem">
<a href="/modules/blueprintannotation.html">Blueprint Annotations</a>
</div>
<div class="menuitem">
<a href="/modules/blueprintnoosgi.html">Blueprint No-OSGi</a>
</div>
<div class="menuitem">
<a href="/modules/blueprintweb.html">Blueprint Web</a>
</div>
<div class="menuitem">
<a href="/modules/containers.html">Containers</a>
</div>
<div class="menuitem">
<a href="/modules/esaanttask.html">ESA Ant Task </a>
</div>
<div class="menuitem">
<a href="/modules/ebamavenpluginproject.html">EBA Maven Plugin </a>
</div>
<div class="menuitem">
<a href="/modules/esamavenpluginproject.html">ESA Maven Plugin </a>
</div>
<div class="menuitem">
<a href="/modules/jmx.html">JMX</a>
</div>
<div class="menuitem">
<a href="/modules/jndiproject.html">JNDI</a>
</div>
<div class="menuitem">
<a href="/modules/jpaproject.html">JPA</a>
</div>
<div class="menuitem">
<a href="/modules/transactioncontrol.html">Transaction Control Service</a>
</div>
<div class="menuitem">
<a href="/modules/transactionsproject.html">Transactions</a>
</div>
<div class="menuitem">
<a href="/modules/rsa.html">Remote Service Admin (RSA)</a>
</div>
<div class="menuitem">
<a href="/modules/spi-fly.html">SPI Fly</a>
</div>
<div class="menuitem">
<a href="/modules/subsystems.html">Subsystems</a>
</div>
<div class="menuitem">
<a href="/modules/applications.html">Applications (obsolete)</a>
</div>
</div>
<div onclick="SwitchMenu('downloads')" id="downloadsTitle" class="menutitle">Downloads</div>
<div id="downloads" class="menuitemgroup">
<div class="menuitem">
<a href="/downloads/currentreleases.html">Current Releases</a>
</div>
<div class="menuitem">
<a href="/downloads/testresults.html">Compliance Tests</a>
</div>
<div class="menuitem">
<a href="/downloads/archived-releases.html">Archived Releases</a>
</div>
</div>
<div onclick="SwitchMenu('community')" id="communityTitle" class="menutitle">Community</div>
<div id="community" class="menuitemgroup">
<div class="menuitem">
<a href="/community/resources.html">Community Resources</a>
</div>
<div class="menuitem">
<a href="/community/gettinginvolved.html">Getting Involved</a>
</div>
<div class="menuitem">
<a href="/community/people.html">Who we are</a>
</div>
<div class="menuitem">
<a href="/community/boardreports.html">Board Reports</a>
</div>
<div class="menuitem">
<a href="/community/logos.html">Logos for Users</a>
</div>
</div>
<div onclick="SwitchMenu('development')" id="developmentTitle" class="menutitle">Development</div>
<div id="development" class="menuitemgroup">
<div class="menuitem">
<a href="/development/buildingaries.html">Building Aries </a>
</div>
<div class="menuitem">
<a href="/development/guidelines.html">Cording Guidelines</a>
</div>
<div class="menuitem">
<a href="/development/architecture.html">Architecture</a>
</div>
<div class="menuitem">
<a href="/development/releasingaries.html">Releasing Aries </a>
</div>
<div class="menuitem">
<a href="/development/compliancetesting.html">OSGi Compliance Tests </a>
</div>
<div class="menuitem">
<a href="/development/maintainingthewebpages.html">Web Site Maintenance </a>
</div>
</div>
<div onclick="SwitchMenu('sponsorship')" id="sponsorshipTitle" class="menutitle">Sponsorship</div>
<div id="sponsorship" class="menuitemgroup">
<div class="menuitem">
<a href="http://www.apache.org/foundation/thanks.html">Thanks</a>
</div>
<div class="menuitem">
<a href="http://www.apache.org/foundation/sponsorship.html">Sponsoring Apache</a>
</div>
</div>
<div class="promotion">
<a href="http://www.apache.org/events/current-event.html">
<img src="http://www.apache.org/events/current-event-125x125.png" width="125" height="125"/>
</a>
</div>
<!-- NavigationBar -->
</div>
</div>
</div>
</div>
</td>
<td height="100%" width="100%">
<!-- Content -->
<div class="wiki-content"><style type="text/css">
/* The following code is added by mdx_elementid.py
It was originally lifted from http://subversion.apache.org/style/site.css */
/*
* Hide class="elementid-permalink", except when an enclosing heading
* has the :hover property.
*/
.headerlink, .elementid-permalink {
visibility: hidden;
}
h2:hover > .headerlink, h3:hover > .headerlink, h1:hover > .headerlink, h6:hover > .headerlink, h4:hover > .headerlink, h5:hover > .headerlink, dt:hover > .elementid-permalink { visibility: visible }</style>
<h1 id="using-the-coordinator-to-optimise-transactions">Using the Coordinator to optimise Transactions<a class="headerlink" href="#using-the-coordinator-to-optimise-transactions" title="Permanent link">&para;</a></h1>
<p>The transaction control service provides a transactional scope around resource access, but sometimes it
makes sense to delay doing this work until it can be batched efficiently together in a single transaction:</p>
<h2 id="bulk-resource-access">Bulk resource access<a class="headerlink" href="#bulk-resource-access" title="Permanent link">&para;</a></h2>
<p>In this case we simply do each insert in a separate transaction:</p>
<div class="codehilite"><pre><span class="n">public</span> <span class="n">void</span> <span class="n">persistMessage</span><span class="p">(</span><span class="n">String</span> <span class="n">message</span><span class="p">)</span> <span class="p">{</span>
<span class="n">txControl</span><span class="p">.</span><span class="n">required</span><span class="p">(()</span> <span class="o">-&gt;</span> <span class="p">{</span>
<span class="n">PreparedStatement</span> <span class="n">ps</span> <span class="p">=</span> <span class="n">connection</span><span class="p">.</span><span class="n">prepareStatement</span><span class="p">(</span>
&quot;<span class="n">Insert</span> <span class="n">into</span> <span class="n">TEST_TABLE</span> <span class="n">values</span> <span class="p">(</span> ? <span class="p">)</span>&quot;<span class="p">);</span>
<span class="n">ps</span><span class="p">.</span><span class="n">setString</span><span class="p">(</span>1<span class="p">,</span> <span class="n">message</span><span class="p">);</span>
<span class="k">return</span> <span class="n">ps</span><span class="p">.</span><span class="n">executeUpdate</span><span class="p">();</span>
<span class="p">});</span>
<span class="p">}</span>
</pre></div>
<p>If called a large number of times from an external service:</p>
<div class="codehilite"><pre><span class="n">List</span><span class="o">&lt;</span><span class="n">String</span><span class="o">&gt;</span> <span class="n">messages</span> <span class="p">=</span> <span class="n">getMessages</span><span class="p">();</span>
<span class="n">messages</span><span class="p">.</span><span class="n">stream</span><span class="p">()</span>
<span class="p">.</span><span class="n">forEach</span><span class="p">(</span><span class="n">svc</span><span class="p">::</span><span class="n">persistMessage</span><span class="p">);</span>
</pre></div>
<p>Then this code can be quite slow as the message list becomes large</p>
<h2 id="the-naive-approach">The naive approach<a class="headerlink" href="#the-naive-approach" title="Permanent link">&para;</a></h2>
<p>The obvious way to reduce overhead is to batch all of the inserts into a single transaction:</p>
<div class="codehilite"><pre><span class="n">List</span><span class="o">&lt;</span><span class="n">String</span><span class="o">&gt;</span> <span class="n">messages</span> <span class="p">=</span> <span class="n">getMessages</span><span class="p">();</span>
<span class="n">txControl</span><span class="p">.</span><span class="n">required</span><span class="p">(()</span> <span class="o">-&gt;</span> <span class="p">{</span>
<span class="n">messages</span><span class="p">.</span><span class="n">stream</span><span class="p">()</span>
<span class="p">.</span><span class="n">forEach</span><span class="p">(</span><span class="n">svc</span><span class="p">::</span><span class="n">persistMessage</span><span class="p">);</span>
<span class="k">return</span> <span class="n">null</span><span class="p">;</span>
<span class="p">});</span>
</pre></div>
<p>This reuses the same physical connection each time, and it avoids repeated commits, so it should be faster
right?</p>
<p>Actually it turns out that this approach can be slower for some databases. By building up a very large
transaction it can actually slow down the rate at which data can be insterted.</p>
<h2 id="using-the-coordinator">Using the coordinator<a class="headerlink" href="#using-the-coordinator" title="Permanent link">&para;</a></h2>
<p>By adding in the Coordinator we can <strong>dramatically</strong> improve our performance:</p>
<div class="codehilite"><pre><span class="n">public</span> <span class="n">void</span> <span class="n">persistMessage</span><span class="p">(</span><span class="n">String</span> <span class="n">message</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span><span class="p">(</span><span class="n">coordinator</span><span class="p">.</span><span class="n">addParticipant</span><span class="p">(</span><span class="n">this</span><span class="p">))</span> <span class="p">{</span>
<span class="p">((</span><span class="n">List</span><span class="o">&lt;</span><span class="n">String</span><span class="o">&gt;</span><span class="p">)</span><span class="n">coordinator</span><span class="p">.</span><span class="n">peek</span><span class="p">().</span><span class="n">getVariables</span><span class="p">()</span>
<span class="p">.</span><span class="n">computeIfAbsent</span><span class="p">(</span><span class="n">getClass</span><span class="p">(),</span> <span class="n">k</span> <span class="o">-&gt;</span> <span class="n">new</span> <span class="n">ArrayList</span><span class="o">&lt;</span><span class="n">String</span><span class="o">&gt;</span><span class="p">()))</span>
<span class="p">.</span><span class="n">add</span><span class="p">(</span><span class="n">message</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="n">txControl</span><span class="p">.</span><span class="n">required</span><span class="p">(()</span> <span class="o">-&gt;</span> <span class="p">{</span>
<span class="n">PreparedStatement</span> <span class="n">ps</span> <span class="p">=</span> <span class="n">connection</span><span class="p">.</span><span class="n">prepareStatement</span><span class="p">(</span>
&quot;<span class="n">Insert</span> <span class="n">into</span> <span class="n">TEST_TABLE</span> <span class="n">values</span> <span class="p">(</span> ? <span class="p">)</span>&quot;<span class="p">);</span>
<span class="n">ps</span><span class="p">.</span><span class="n">setString</span><span class="p">(</span>1<span class="p">,</span> <span class="n">message</span><span class="p">);</span>
<span class="k">return</span> <span class="n">ps</span><span class="p">.</span><span class="n">executeUpdate</span><span class="p">();</span>
<span class="p">});</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">@</span><span class="n">Override</span>
<span class="n">public</span> <span class="n">void</span> <span class="n">ended</span><span class="p">(</span><span class="n">Coordination</span> <span class="n">coord</span><span class="p">)</span> <span class="n">throws</span> <span class="n">Exception</span> <span class="p">{</span>
<span class="n">txControl</span><span class="p">.</span><span class="n">required</span><span class="p">(()</span> <span class="o">-&gt;</span> <span class="p">{</span>
<span class="n">List</span><span class="o">&lt;</span><span class="n">String</span><span class="o">&gt;</span> <span class="n">l</span> <span class="p">=</span> <span class="p">(</span><span class="n">List</span><span class="o">&lt;</span><span class="n">String</span><span class="o">&gt;</span><span class="p">)</span> <span class="n">coord</span><span class="p">.</span><span class="n">getVariables</span><span class="p">()</span>
<span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="n">getClass</span><span class="p">());</span>
<span class="n">PreparedStatement</span> <span class="n">ps</span> <span class="p">=</span> <span class="n">connection</span><span class="p">.</span><span class="n">prepareStatement</span><span class="p">(</span>
&quot;<span class="n">Insert</span> <span class="n">into</span> <span class="n">TEST_TABLE</span> <span class="n">values</span> <span class="p">(</span> ? <span class="p">)</span>&quot;<span class="p">);</span>
<span class="n">l</span><span class="p">.</span><span class="n">stream</span><span class="p">().</span><span class="n">forEach</span><span class="p">(</span><span class="n">s</span> <span class="o">-&gt;</span> <span class="p">{</span>
<span class="k">try</span> <span class="p">{</span>
<span class="n">ps</span><span class="p">.</span><span class="n">setString</span><span class="p">(</span>1<span class="p">,</span> <span class="n">s</span><span class="p">);</span>
<span class="n">ps</span><span class="p">.</span><span class="n">addBatch</span><span class="p">();</span>
<span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="n">SQLException</span> <span class="n">sqle</span><span class="p">)</span> <span class="p">{</span>
<span class="n">throw</span> <span class="n">new</span> <span class="n">RuntimeException</span><span class="p">(</span><span class="n">sqle</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="k">return</span> <span class="n">ps</span><span class="p">.</span><span class="n">executeBatch</span><span class="p">();</span>
<span class="p">});</span>
<span class="p">}</span>
</pre></div>
<p>Now, if we do our bulk add inside a coordination:</p>
<div class="codehilite"><pre><span class="n">coordinator</span><span class="p">.</span><span class="n">begin</span><span class="p">(</span>&quot;<span class="n">foo</span>&quot;<span class="p">,</span> <span class="n">MINUTES</span><span class="p">.</span><span class="n">toMillis</span><span class="p">(</span>5<span class="p">));</span>
<span class="k">try</span> <span class="p">{</span>
<span class="n">messages</span><span class="p">.</span><span class="n">stream</span><span class="p">()</span>
<span class="p">.</span><span class="n">forEach</span><span class="p">(</span><span class="n">this</span><span class="p">::</span><span class="n">persistMessage</span><span class="p">);</span>
<span class="p">}</span> <span class="n">finally</span> <span class="p">{</span>
<span class="n">coordinator</span><span class="p">.</span><span class="n">peek</span><span class="p">().</span><span class="k">end</span><span class="p">();</span>
<span class="p">}</span>
</pre></div>
<p>Then we find that it is <strong>much</strong> faster! This is because we can make use of more efficient JDBC API, and
because we can batch up a suitable number of inserts in a single transaction.</p></div>
<!-- Content -->
</td>
</tr>
</table>
</td>
<td id="cell-2-2" colspan="2">&nbsp;</td>
</tr>
<tr width="100%">
<td id="cell-3-0">&nbsp;</td>
<td id="cell-3-1">&nbsp;</td>
<td id="cell-3-2">
<div id="footer">
<!-- Footer -->
<div id="site-footer">
<a href="http://aries.apache.org/privacy-policy.html";>Privacy
Policy</a>
</div>
<!-- Footer -->
</div>
</td>
<td id="cell-3-3">&nbsp;</td>
<td id="cell-3-4">&nbsp;</td>
</tr>
<tr width="100%">
<td id="cell-4-0" colspan="2">&nbsp;</td>
<td id="cell-4-1">&nbsp;</td>
<td id="cell-4-2" colspan="2">&nbsp;</td>
</tr>
</table>
</body>
</html>