| <!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"> </td> |
| <td id="cell-0-1"> </td> |
| <td id="cell-0-2" colspan="2"> </td> |
| </tr> |
| <tr width="100%"> |
| <td id="cell-1-0"> </td> |
| <td id="cell-1-1"> </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"> </td> |
| <td id="cell-1-4"> </td> |
| </tr> |
| <tr width="100%"> |
| <td id="cell-2-0" colspan="2"> </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">¶</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">¶</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">-></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">¶</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">¶</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">-></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">-></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">¶</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">¶</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">¶</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"><</span><span class="n">T</span><span class="o">></span> <span class="n">T</span> <span class="n">search</span><span class="p">(</span><span class="n">Class</span><span class="o"><</span><span class="n">T</span><span class="o">></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">¶</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">¶</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">¶</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">¶</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">-></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">-></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">¶</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"> </td> |
| </tr> |
| <tr width="100%"> |
| <td id="cell-3-0"> </td> |
| <td id="cell-3-1"> </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"> </td> |
| <td id="cell-3-4"> </td> |
| </tr> |
| <tr width="100%"> |
| <td id="cell-4-0" colspan="2"> </td> |
| <td id="cell-4-1"> </td> |
| <td id="cell-4-2" colspan="2"> </td> |
| </tr> |
| </table> |
| </body> |
| </html> |