mongodb-odm-docs-dash/Doctrine ODM.docset/Contents/Resources/Documents/reference/change-tracking-policies.html

280 lines
15 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Change Tracking Policies &mdash; Doctrine MongoDB ODM 1.1.5 documentation</title>
<link rel="stylesheet" href="../_static/bootstrap/css/bootstrap.min.css" type="text/css" />
<link rel="stylesheet" href="../_static/default.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../_static/layout.css" type="text/css" />
<link rel="stylesheet" href="../_static/configurationblock.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../',
VERSION: '1.1.5',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/configurationblock.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/configurationblock.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<script type="text/javascript" src="../_static/configurationblock.js"></script>
<script src="../_static/bootstrap/js/bootstrap.min.js"></script>
<script type="text/javascript">
<!--
$(document).ready(function() {
$("#versions").change(function() {
var docsUrl = $(this).val();
window.location.href = docsUrl;
});
});
-->
</script>
<link rel="shortcut icon" href="../_static/doctrine.ico"/>
<link rel="search" title="Search" href="../search.html" />
<link rel="top" title="Doctrine MongoDB ODM 1.1.5 documentation" href="../index.html" />
</head>
<body>
<div id="wrapper">
<div id="header">
<h1 id="h1title"></h1>
<div id="logo">
<a href="http://www.doctrine-project.org/">Doctrine - PHP Database Libraries</a>
</div>
</div>
<div id="nav" class="cls">
<div class="tl cls">
<ul>
<li><a target="_top" href="http://www.doctrine-project.org/">Home</a></li>
<li><a target="_top" href="http://www.doctrine-project.org/about.html">About</a></li>
<li><a target="_top" href="http://www.doctrine-project.org/projects.html">Projects</a></li>
<li><a target="_top" href="http://www.doctrine-project.org/contribute.html">Contribute</a></li>
<li><a target="_top" href="http://www.doctrine-project.org/community.html">Community</a></li>
<li><a target="_top" href="http://www.doctrine-project.org/archive.html">Blog</a></li>
<li><a target="_top" href="http://www.doctrine-project.org/jira">Development</a></li>
</ul>
</div>
</div>
<div id="content" class="cls">
<div class="related">
<h3>Navigation</h3>
<ul>
<li><a href="/">Doctrine Homepage</a> &raquo;</li>
<li><a href="../index.html">Doctrine MongoDB ODM 1.1.5 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" >
<div class="section" id="change-tracking-policies">
<span id="id1"></span><h1>Change Tracking Policies<a class="headerlink" href="#change-tracking-policies" title="Permalink to this headline"></a></h1>
<p>Change tracking is the process of determining what has changed in
managed documents since the last time they were synchronized with
the database.</p>
<p>Doctrine provides 3 different change tracking policies, each having
its particular advantages and disadvantages. The change tracking
policy can be defined on a per-class basis (or more precisely,
per-hierarchy).</p>
<div class="section" id="deferred-implicit">
<h2>Deferred Implicit<a class="headerlink" href="#deferred-implicit" title="Permalink to this headline"></a></h2>
<p>The deferred implicit policy is the default change tracking policy
and the most convenient one. With this policy, Doctrine detects the
changes by a property-by-property comparison at commit time and
also detects changes to documents or new documents that are
referenced by other managed documents. Although the most convenient policy,
it can have negative effects on performance if you are dealing with large units
of work. Since Doctrine can't know what has changed, it needs to check
all managed documents for changes every time you invoke DocumentManager#flush(),
making this operation rather costly.</p>
</div>
<div class="section" id="deferred-explicit">
<h2>Deferred Explicit<a class="headerlink" href="#deferred-explicit" title="Permalink to this headline"></a></h2>
<p>The deferred explicit policy is similar to the deferred implicit
policy in that it detects changes through a property-by-property
comparison at commit time. The difference is that only documents are
considered that have been explicitly marked for change detection
through a call to DocumentManager#persist(document) or through a save
cascade. All other documents are skipped. This policy therefore
gives improved performance for larger units of work while
sacrificing the behavior of &quot;automatic dirty checking&quot;.</p>
<p>Therefore, flush() operations are potentially cheaper with this
policy. The negative aspect this has is that if you have a rather
large application and you pass your objects through several layers
for processing purposes and business tasks you may need to track
yourself which documents have changed on the way so you can pass
them to DocumentManager#persist().</p>
<p>This policy can be configured as follows:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="sd">/**</span>
<span class="sd"> * @Document</span>
<span class="sd"> * @ChangeTrackingPolicy(&quot;DEFERRED_EXPLICIT&quot;)</span>
<span class="sd"> */</span>
<span class="k">class</span> <span class="nc">User</span>
<span class="p">{</span>
<span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="notify">
<h2>Notify<a class="headerlink" href="#notify" title="Permalink to this headline"></a></h2>
<p>This policy is based on the assumption that the documents notify
interested listeners of changes to their properties. For that
purpose, a class that wants to use this policy needs to implement
the <code class="docutils literal"><span class="pre">NotifyPropertyChanged</span></code> interface from the Doctrine
namespace. As a guideline, such an implementation can look as
follows:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">use</span> <span class="nx">Doctrine\Common\NotifyPropertyChanged</span><span class="p">,</span>
<span class="nx">Doctrine\Common\PropertyChangedListener</span><span class="p">;</span>
<span class="sd">/**</span>
<span class="sd"> * @Document</span>
<span class="sd"> * @ChangeTrackingPolicy(&quot;NOTIFY&quot;)</span>
<span class="sd"> */</span>
<span class="k">class</span> <span class="nc">MyDocument</span> <span class="k">implements</span> <span class="nx">NotifyPropertyChanged</span>
<span class="p">{</span>
<span class="c1">// ...</span>
<span class="k">private</span> <span class="nv">$_listeners</span> <span class="o">=</span> <span class="k">array</span><span class="p">();</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">addPropertyChangedListener</span><span class="p">(</span><span class="nx">PropertyChangedListener</span> <span class="nv">$listener</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_listeners</span><span class="p">[]</span> <span class="o">=</span> <span class="nv">$listener</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Then, in each property setter of this class or derived classes, you
need to notify all the <code class="docutils literal"><span class="pre">PropertyChangedListener</span></code> instances. As an
example we add a convenience method on <code class="docutils literal"><span class="pre">MyDocument</span></code> that shows this
behavior:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="c1">// ...</span>
<span class="k">class</span> <span class="nc">MyDocument</span> <span class="k">implements</span> <span class="nx">NotifyPropertyChanged</span>
<span class="p">{</span>
<span class="c1">// ...</span>
<span class="k">protected</span> <span class="k">function</span> <span class="nf">_onPropertyChanged</span><span class="p">(</span><span class="nv">$propName</span><span class="p">,</span> <span class="nv">$oldValue</span><span class="p">,</span> <span class="nv">$newValue</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_listeners</span><span class="p">)</span> <span class="p">{</span>
<span class="k">foreach</span> <span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_listeners</span> <span class="k">as</span> <span class="nv">$listener</span><span class="p">)</span> <span class="p">{</span>
<span class="nv">$listener</span><span class="o">-&gt;</span><span class="na">propertyChanged</span><span class="p">(</span><span class="nv">$this</span><span class="p">,</span> <span class="nv">$propName</span><span class="p">,</span> <span class="nv">$oldValue</span><span class="p">,</span> <span class="nv">$newValue</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">setData</span><span class="p">(</span><span class="nv">$data</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">$data</span> <span class="o">!=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">data</span><span class="p">)</span> <span class="p">{</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_onPropertyChanged</span><span class="p">(</span><span class="s1">&#39;data&#39;</span><span class="p">,</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">data</span><span class="p">,</span> <span class="nv">$data</span><span class="p">);</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">data</span> <span class="o">=</span> <span class="nv">$data</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>You have to invoke <code class="docutils literal"><span class="pre">_onPropertyChanged</span></code> inside every method that
changes the persistent state of <code class="docutils literal"><span class="pre">MyDocument</span></code>.</p>
<p>The check whether the new value is different from the old one is
not mandatory but recommended. That way you also have full control
over when you consider a property changed.</p>
<p>The negative point of this policy is obvious: You need implement an
interface and write some plumbing code. But also note that we tried
hard to keep this notification functionality abstract. Strictly
speaking, it has nothing to do with the persistence layer. You may
find that property notification events come in handy in many other
scenarios as well. As mentioned earlier, the <code class="docutils literal"><span class="pre">Doctrine\Common</span></code>
namespace is not that evil and consists solely of very small classes
and interfaces that have almost no external dependencies and that you can easily take with you should
you want to swap out the persistence layer. This change tracking policy
does not introduce a dependency on the Doctrine persistence
layer.</p>
<p>The positive point and main advantage of this policy is its
effectiveness. It has the best performance characteristics of the 3
policies with larger units of work and a flush() operation is very
cheap when nothing has changed.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<div id="searchbox" style="">
<h3>Search</h3>
<form class="search" action="http://readthedocs.org/search/project/" method="get">
<input type="text" name="q" size="18">
<input type="submit" value="Go">
<input type="hidden" name="selected_facets" value="project:">
</form>
</div>
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Change Tracking Policies</a><ul>
<li><a class="reference internal" href="#deferred-implicit">Deferred Implicit</a></li>
<li><a class="reference internal" href="#deferred-explicit">Deferred Explicit</a></li>
<li><a class="reference internal" href="#notify">Notify</a></li>
</ul>
</li>
</ul>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/change-tracking-policies.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&copy; Copyright 2013, Doctrine Project Team.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.6.2.
<br/>
<a target="_BLANK" href="http://www.servergrove.com"><img src="http://www.doctrine-project.org/_static/servergrove.jpg" /></a> <br/><br/>
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_s-xclick" />
<input type="hidden" name="hosted_button_id" value="BAE2E3XANQ77Y" />
<input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!" />
<img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" />
</form>
</div>
</div>
<div id="bot-rcnr">
<div class="tl"><!-- corner --></div>
</div>
</div>
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-288343-7";
urchinTracker();
</script>
<a class="githublink" href="http://github.com/doctrine"><img src="https://s3.amazonaws.com/github/ribbons/forkme_right_orange_ff7600.png" alt="Fork me on GitHub"></a>
</body>
</html>