HTML-ListToTree
view release on metacpan or search on metacpan
examples/Sociable.pod.html view on Meta::CPAN
are <strong>not</strong> restartable/abortable inside STM transactions. However,
as for thread-private variable, it may be possible to provide some
level of recoverability via the onRestart/onRollback closures.</p>
<h1 id="Using_STM">Using STM <a href="#TOP" class="toplink"><img alt="^" src="..\up.gif" /></a></h1>
<p>Currently, STM is only supported on x86, x64, SPARC, and PowerPC
CPU platforms (due to the availability of spinlock code).
Support for other CPUs may be possible, assuming appropriate
spinlock code is provided <i>(patches welcome)</i>.</p>
<p>An STM transaction will be restarted if any of the following
occur during the transaction:</p>
<ul>
<li>Another thread modifies a scalar previously read by the current
thread (including an individual array or hash element)</li>
<li>Another thread adds or deletes elements from a sociable array previously
read by the current thread, regardless whether the current transaction
accesses the added/removed elements, due to potential
conflict with a prior <code>scalar @array</code> or <code>$#array</code> reference.</li>
<li>Another thread adds or deletes an element from a sociable hash
previously read by the current thread, regardless whether the current transaction
accesses the added/removed elements, due to potential
conflict with a prior <code>keys %hash</code> reference.</li>
<li>The transaction explicitly <code>die</code>'s with the message
"Thread::Sociable STM RESTART".</li>
<li>The contention manager forces a restart to avoid livelocks <i>See "STM Implementation Details"
below</i>.</li>
</ul>
<p>Restart and rollback <strong>cannot</strong> rollback any external effects of,
or changes to, thread-private variables or I/O operations. E.g.,
if an application writes to a file during a transaction which later restarts
or rolls back, the file write operation is not rolled back. Applications
can, however, provide logic to perform such rollbacks via
the <code>onRestart</code> and <code>onRollback</code> closure arguments.</p>
<p>Threads spawned within a transaction <strong>do not</strong> inherit the
transaction state.</p>
<p>Processes forked within a transaction will inherit any current transactions
within the current threads; however, as the new process's address space
is completely separate from parent process, the transactions
of one process <strong>do not</strong> effect the transactions of another.</p>
<p><code>onCommit</code> closures may induce either restart or rollback by executing
an appropriate <code>die</code>. <code>onRestart</code> closures may induce rollback by executing a <code>die</code>.
<code>onRollback</code> closures <strong>cannot</strong> induce a restart.</p>
<p>Attempting to open a new transaction in <code>onCommit</code>, <code>onRestart</code>, or <code>onRollback</code>
closures will generate a fatal error. Any access to sociable variables within those
closures will <strong>not</strong> be transactional, and will reference the sociable value,
<strong>not</strong> any existing private transactional value.</p>
<p>Transactions may be nested; however,</p>
<ul>
<li>Commits of sequential inner transactions
are <strong>not</strong> applied until the outermost transaction commits.</li>
<li>Restarts or rollbacks of inner transactions will cascade to <strong>all</strong>
transactions within the thread, including previously completed, but
uncommitted, preceding and inner transactions.</li>
</ul>
<p>As each pending transaction is committed, restarted, or rolled back,
any associated <code>onCmmit</code>, <code>onRestart</code>, or <code>onRollback</code> closures will be invoked.</p>
<p>If a transaction's <code>onCommit</code> closure induces restart or rollback,
or if a transaction's <code>onRestart</code> closure induces rollback,
the <code>onRestart</code> or <code>onRollback</code> closures of <strong>all</strong> pending transactions will be executed,
including</p>
<ul>
<li>prior completed, but uncommitted, transactions</li>
<li>inner transactions</li>
<li>transactions which have already executed their <code>onCommit</code> or <code>onRestart</code> closures</li>
</ul>
<p>Note that certain pathological constructs should be avoided, e.g., consider</p>
<pre> sub lots_of_pending_xactions {
for (1..1000) {
sociable_begin_work(sub {
#
# do some stuff
#
},
onRestart => sub {
#
# do some restart stuff
#
},
onRollback => sub {
#
# do some rollback stuff
#
}
);
}
}
sociable_begin_work(sub {
lots_of_pending_xactions()
#
# do some stuff
#
}
);
</pre><p>This code would cause up to 1000 inner transactions to be completed, but not committed.
More importantly, each iteration would add an additional onRestart and onRollback
closure to the transaction log; if a restart or rollback occurs, <strong>each of the
registered closure instances will be executed</strong>.</p>
<p>In such cases, applications should use a more conservative strategy if possible, e.g.</p>
<pre> sub lots_of_pending_xactions {
my $already_registered = 0;
for (1..1000) {
sociable_begin_work(sub {
( run in 1.049 second using v1.01-cache-2.11-cpan-9581c071862 )