blob: ac1466674f006ae283dabe2475d5df6505479aed [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 -
</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="migrating-from-declarative-transactions">Migrating from declarative transactions<a class="headerlink" href="#migrating-from-declarative-transactions" title="Permanent link">&para;</a></h1>
<p>Many popular application containers, such as Spring or Java EE, offer declarative transaction management.
Specifically, the container offers a model where transaction boundaries are defined using metadata, usually as
annotations on public methods.</p>
<h2 id="the-basics">The Basics<a class="headerlink" href="#the-basics" title="Permanent link">&para;</a></h2>
<p>A typical transactional method in a declarative model might look like this:</p>
<div class="codehilite"><pre><span class="p">@</span><span class="n">Transactional</span>
<span class="n">public</span> <span class="n">Long</span> <span class="n">getCustomerId</span><span class="p">(</span><span class="n">String</span> <span class="n">email</span><span class="p">)</span> <span class="p">{</span>
<span class="o">//</span> <span class="n">Some</span> <span class="n">business</span> <span class="n">logic</span> <span class="n">in</span> <span class="n">here</span><span class="p">...</span>
<span class="p">}</span>
</pre></div>
<p>Using Transaction control the same thing would look like:</p>
<div class="codehilite"><pre><span class="n">public</span> <span class="n">Long</span> <span class="n">getCustomerId</span><span class="p">(</span><span class="n">String</span> <span class="n">email</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="o">//</span> <span class="n">Some</span> <span class="n">business</span> <span class="n">logic</span> <span class="n">in</span> <span class="n">here</span><span class="p">...</span>
<span class="p">});</span>
<span class="p">}</span>
</pre></div>
<p>The main change is that the transactions have moved from being metadata defined, and started by the container,
to being code defined and started by the Transaction Control service. This gives several significant advantages.</p>
<h2 id="the-scoping-problem">The Scoping Problem<a class="headerlink" href="#the-scoping-problem" title="Permanent link">&para;</a></h2>
<p>When using method-level metadata to define transaction boundaries it is not possible to manage transactions
on a finer level. This makes it difficult to suspend or nest transactions unless you create a new method to hold
the extra logic.</p>
<h3 id="a-simple-example">A Simple Example<a class="headerlink" href="#a-simple-example" title="Permanent link">&para;</a></h3>
<p>If we want to write an audit message it usually needs to occur in a new transaction, as typically it should persist
even if the overall action fails. In a declarative model this requires a separate method with a new boundary,
even if the audit function is a private implementation detail of the Object.</p>
<div class="codehilite"><pre><span class="p">@</span><span class="n">Transactional</span>
<span class="n">public</span> <span class="n">void</span> <span class="n">changePassword</span><span class="p">(</span><span class="n">String</span> <span class="n">email</span><span class="p">,</span> <span class="n">String</span> <span class="n">password</span><span class="p">)</span> <span class="p">{</span>
<span class="n">auditPasswordChangeAttempt</span><span class="p">(</span><span class="n">email</span><span class="p">);</span>
<span class="o">//</span> <span class="n">Some</span> <span class="n">business</span> <span class="n">logic</span> <span class="n">in</span> <span class="n">here</span><span class="p">...</span>
<span class="p">}</span>
<span class="p">@</span><span class="n">Transactional</span><span class="p">(</span><span class="n">REQUIRES_NEW</span><span class="p">)</span>
<span class="n">public</span> <span class="n">void</span> <span class="n">auditPasswordChangeAttempt</span><span class="p">(</span><span class="n">String</span> <span class="n">email</span><span class="p">)</span> <span class="p">{</span>
<span class="o">//</span> <span class="n">One</span> <span class="n">line</span> <span class="n">to</span> <span class="n">write</span> <span class="n">the</span> <span class="n">audit</span> <span class="n">message</span>
<span class="p">}</span>
</pre></div>
<p>With transaction control there is no need to create a method just for the internal audit function.</p>
<p>@Transactional
public void changePassword(String email, String password) {</p>
<div class="codehilite"><pre> <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">txControl</span><span class="p">.</span><span class="n">requiresNew</span><span class="p">(()</span> <span class="o">-&gt;</span> <span class="p">{</span>
<span class="o">//</span> <span class="n">One</span> <span class="n">line</span> <span class="n">to</span> <span class="n">write</span> <span class="n">the</span> <span class="n">audit</span> <span class="n">message</span>
<span class="p">});</span>
<span class="o">//</span> <span class="n">Some</span> <span class="n">business</span> <span class="n">logic</span> <span class="n">in</span> <span class="n">here</span><span class="p">...</span>
<span class="p">});</span>
<span class="p">}</span>
</pre></div>
<h2 id="the-proxy-problem">The Proxy Problem<a class="headerlink" href="#the-proxy-problem" title="Permanent link">&para;</a></h2>
<p>The Proxy problem is a rather insidious issue that affects declarative transactions, and it is a result of how they
are implemented. If bytecode weaving is used to directly add transactional behaviour to an object then it will
always work the same way. Most solutions, however, do not use bytecode weaving, but instead use a proxy
pattern. When a call is made on the proxy the proxy will perform any necessary transaction management
before and after delegating the call to the real object. This works well, except if the object makes any internal
method calls.</p>
<p>In the general case proxying is unsafe because you cannot rely on a method's metadata to decide what
transaction state will exist when it is called!</p>
<h3 id="examples-of-the-proxy-problem">Examples of the Proxy Problem<a class="headerlink" href="#examples-of-the-proxy-problem" title="Permanent link">&para;</a></h3>
<p>The following examples are all based on real code migrated from Spring to Transaction Control.</p>
<h4 id="a-simple-example_1">A Simple Example<a class="headerlink" href="#a-simple-example_1" title="Permanent link">&para;</a></h4>
<div class="codehilite"><pre><span class="n">AbstractPersistenceDataManagerImpl</span> <span class="p">{</span>
<span class="p">@</span><span class="n">Transactional</span><span class="p">(</span><span class="n">propagation</span> <span class="p">=</span> <span class="n">SUPPORTS</span><span class="p">,</span> <span class="n">readOnly</span> <span class="p">=</span> <span class="n">true</span><span class="p">)</span>
<span class="n">public</span> <span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="n">T</span> <span class="n">search</span><span class="p">(</span><span class="n">Class</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="n">entityClass</span><span class="p">,</span> <span class="n">Object</span> <span class="n">pk</span><span class="p">,</span> <span class="n">Object</span> <span class="n">params</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="p">(</span><span class="n">T</span><span class="p">)</span> <span class="nb">find</span><span class="p">(</span><span class="n">entityClass</span><span class="p">,</span> <span class="n">pk</span><span class="p">,</span> <span class="n">params</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">@</span><span class="n">Transactional</span><span class="p">(</span><span class="n">readOnly</span> <span class="p">=</span> <span class="n">true</span><span class="p">)</span>
<span class="n">public</span> <span class="n">UniWorksSuperDBEntity</span> <span class="nb">find</span><span class="p">(</span><span class="n">Class</span> <span class="n">entityClass</span><span class="p">,</span> <span class="n">Object</span> <span class="n">pk</span><span class="p">,</span> <span class="n">Object</span> <span class="n">params</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="p">(</span><span class="n">UniWorksSuperDBEntity</span><span class="p">)</span> <span class="n">em</span><span class="p">.</span><span class="nb">find</span><span class="p">(</span><span class="n">entityClass</span><span class="p">,</span> <span class="n">pk</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
<p>In this case the <code>search</code> method does not require a transaction, but delegates to the
<code>find</code> method which does. If proxying is used then the <code>find</code> method will
sometimes run in a transaction and sometimes not. On the other hand, if weaving is used then the
<code>find</code> method will <em>always</em> run under a transaction This may seem innocuous, but it
can cause big problems. We always want to be certain about where a transaction will start and stop!</p>
<h4 id="extending-the-simple-example">Extending the Simple Example<a class="headerlink" href="#extending-the-simple-example" title="Permanent link">&para;</a></h4>
<p>The following type is part of the same project as the previous example, and interacts with it.</p>
<div class="codehilite"><pre><span class="n">AbstractDataManager</span> <span class="p">{</span>
<span class="p">@</span><span class="n">Transactional</span><span class="p">(</span><span class="n">propagation</span> <span class="p">=</span> <span class="n">NOT_SUPPORTED</span><span class="p">,</span> <span class="n">readOnly</span> <span class="p">=</span> <span class="n">true</span><span class="p">)</span>
<span class="n">public</span> <span class="n">UniWorksSuperDTO</span> <span class="n">search</span><span class="p">(</span><span class="n">Object</span> <span class="n">pk</span><span class="p">,</span> <span class="n">Object</span> <span class="n">params</span><span class="p">)</span> <span class="p">{</span>
<span class="n">UniWorksSuperDBEntity</span> <span class="n">entity</span> <span class="p">=</span> <span class="n">persistenceDataManager</span>
<span class="p">.</span><span class="n">search</span><span class="p">(</span><span class="n">getEntityClass</span><span class="p">(),</span> <span class="n">createNewPKFromDTOPK</span><span class="p">(</span><span class="n">pk</span><span class="p">),</span> <span class="n">null</span><span class="p">);</span>
<span class="n">loadLinkedTablesTop</span><span class="p">(</span><span class="n">entity</span><span class="p">,</span> <span class="n">params</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">protected</span> <span class="n">final</span> <span class="n">void</span> <span class="n">loadLinkedTablesTop</span><span class="p">(</span><span class="n">UniWorksSuperDBEntity</span> <span class="n">entity</span><span class="p">,</span> <span class="n">Object</span> <span class="n">params</span><span class="p">)</span> <span class="p">{</span>
<span class="n">loadLinkedTables</span><span class="p">(</span><span class="n">entity</span><span class="p">,</span> <span class="n">params</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">@</span><span class="n">Transactional</span><span class="p">(</span><span class="n">readOnly</span> <span class="p">=</span> <span class="n">true</span><span class="p">)</span>
<span class="n">public</span> <span class="n">void</span> <span class="n">loadLinkedTables</span><span class="p">(</span><span class="n">UniWorksSuperDBEntity</span> <span class="n">entity</span><span class="p">,</span> <span class="n">Object</span> <span class="n">params</span><span class="p">)</span> <span class="p">{</span>
<span class="n">loadLinkedTablesGenerated</span><span class="p">(</span><span class="n">entity</span><span class="p">,</span> <span class="n">params</span><span class="p">);</span>
<span class="n">loadLinkedTransients</span><span class="p">(</span><span class="n">entity</span><span class="p">,</span> <span class="n">params</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
<p>Now lets imagine that a call comes in to the <code>search</code> method of this class from some client.</p>
<h5 id="proxied">Proxied<a class="headerlink" href="#proxied" title="Permanent link">&para;</a></h5>
<ol>
<li>The container proxy for the data manager halts any ongoing transaction due to the
<code>NOT_SUPPORTED</code> metadata, entering an undefined scope.</li>
<li>The code calls search on the persistenceDataManager</li>
<li>The container proxy for the persistence data manager does not start or stop a transaction due to the
<code>SUPPORTS</code> scope.</li>
<li>The code calls <code>find</code> on the persistenceDataManager, but without touching the proxy.</li>
<li>The code accesses the entity outside a transaction</li>
<li>The code returns the entity, and no transaction change is necessary</li>
<li>The code calls loadLinkedTablesTop, which calls loadLinkedTables. No proxy is touched therefore no
transaction is started.</li>
<li>The Tables are populated with data from the entity. Lazy loading is possible as the entity is still attached.</li>
</ol>
<h5 id="woven">Woven<a class="headerlink" href="#woven" title="Permanent link">&para;</a></h5>
<ol>
<li>The weaving code for the data manager halts any ongoing transaction due to the
<code>NOT_SUPPORTED</code> metadata, entering an undefined scope.</li>
<li>The code calls search on the persistenceDataManager</li>
<li>The weaving code for the persistence data manager does not start or stop a transaction due to the
<code>SUPPORTS</code> scope.</li>
<li>The code calls <code>find</code> on the persistenceDataManager, at this point the weaving code starts
a transaction.</li>
<li>The code accesses the entity inside the transaction</li>
<li>The code returns the entity, and the transaction completes. This detaches the entity and prevents lazy loading.</li>
<li>The code calls loadLinkedTablesTop, which calls loadLinkedTables. The weaving code starts a new
transaction.</li>
<li>The Code fails as the entity is not able to access its lazily loaded data.</li>
</ol>
<h3 id="strategies-for-managing-transaction-states">Strategies for Managing Transaction States<a class="headerlink" href="#strategies-for-managing-transaction-states" title="Permanent link">&para;</a></h3>
<p>Ensuring consistency is vital when writing code that uses transactions. It is therefore usually a good idea to
ensure that any reused code is captured in a private method, and that it asserts the correct transaction state
before it begins.</p>
<div class="codehilite"><pre><span class="n">AbstractDataManager</span> <span class="p">{</span>
<span class="n">public</span> <span class="n">UniWorksSuperDTO</span> <span class="n">search</span><span class="p">(</span><span class="n">Object</span> <span class="n">pk</span><span class="p">,</span> <span class="n">Object</span> <span class="n">params</span><span class="p">)</span> <span class="p">{</span>
<span class="n">txControl</span><span class="p">.</span><span class="n">build</span><span class="p">().</span><span class="n">readOnly</span><span class="p">().</span><span class="n">notSupported</span><span class="p">(()</span> <span class="o">-&gt;</span> <span class="p">{</span>
<span class="n">UniWorksSuperDBEntity</span> <span class="n">entity</span> <span class="p">=</span> <span class="n">persistenceDataManager</span>
<span class="p">.</span><span class="n">search</span><span class="p">(</span><span class="n">getEntityClass</span><span class="p">(),</span> <span class="n">createNewPKFromDTOPK</span><span class="p">(</span><span class="n">pk</span><span class="p">),</span> <span class="n">null</span><span class="p">);</span>
<span class="n">loadLinkedTablesTop</span><span class="p">(</span><span class="n">entity</span><span class="p">,</span> <span class="n">params</span><span class="p">);</span>
<span class="k">return</span> <span class="n">entity</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="n">protected</span> <span class="n">final</span> <span class="n">void</span> <span class="n">loadLinkedTablesTop</span><span class="p">(</span><span class="n">UniWorksSuperDBEntity</span> <span class="n">entity</span><span class="p">,</span> <span class="n">Object</span> <span class="n">params</span><span class="p">)</span> <span class="p">{</span>
<span class="n">loadLinkedTables</span><span class="p">(</span><span class="n">entity</span><span class="p">,</span> <span class="n">params</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">public</span> <span class="n">void</span> <span class="n">loadLinkedTables</span><span class="p">(</span><span class="n">UniWorksSuperDBEntity</span> <span class="n">entity</span><span class="p">,</span> <span class="n">Object</span> <span class="n">params</span><span class="p">)</span> <span class="p">{</span>
<span class="n">txControl</span><span class="p">.</span><span class="n">build</span><span class="p">().</span><span class="n">readOnly</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">loadLinkedTables</span><span class="p">(</span><span class="n">entity</span><span class="p">,</span> <span class="n">params</span><span class="p">);</span>
<span class="p">});</span>
<span class="p">}</span>
<span class="o">/**</span>
<span class="o">*</span> <span class="n">This</span> <span class="n">method</span> <span class="n">does</span> <span class="n">not</span> <span class="n">need</span> <span class="n">a</span> <span class="n">transaction</span><span class="p">,</span> <span class="n">but</span> <span class="n">does</span> <span class="n">need</span> <span class="n">a</span> <span class="n">scope</span>
<span class="o">*/</span>
<span class="n">private</span> <span class="n">void</span> <span class="n">loadLinkedTablesInternal</span><span class="p">(</span><span class="n">UniWorksSuperDBEntity</span> <span class="n">entity</span><span class="p">,</span> <span class="n">Object</span> <span class="n">params</span><span class="p">)</span> <span class="p">{</span>
<span class="n">assert</span> <span class="n">txControl</span><span class="p">.</span><span class="n">activeScope</span><span class="p">();</span>
<span class="n">loadLinkedTablesGenerated</span><span class="p">(</span><span class="n">entity</span><span class="p">,</span> <span class="n">params</span><span class="p">);</span>
<span class="n">loadLinkedTransients</span><span class="p">(</span><span class="n">entity</span><span class="p">,</span> <span class="n">params</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
<p>Writing code in this way ensures that even when a mixture of transactional and non transactional actions are
needed, there will always be a consistent expectation of the transaction scope in each method.</p>
<h2 id="exception-management">Exception management<a class="headerlink" href="#exception-management" title="Permanent link">&para;</a></h2>
<p>The final significant difference between declarative models and the Transaction Control Service is in how much
work your application code needs to do when managing exceptions. More detail about managing exceptions
<a href="exceptionManagement.html">is available here</a>.</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>