Sophie

Sophie

distrib > Mandriva > 2008.1 > x86_64 > media > main-testing > by-pkgid > 91128064e1b251eab84e1c0e3ea0dd7a > files > 189

lib64mysql-devel-5.0.51a-8mdv2008.1.x86_64.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>NDB API Programmers&#39; Guide</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
<link href="tabs.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.5.5 -->
<div class="contents">
<h1>NDB API Programmers' Guide</h1>
<p>
This guide assumes a basic familiarity with MySQL Cluster concepts found on <a href="http://dev.mysql.com/doc/mysql/en/NDBCluster.html">http://dev.mysql.com/doc/mysql/en/NDBCluster.html</a> . Some of the fundamental ones are also described in section <a class="el" href="secConcepts.html">MySQL Cluster Concepts</a>.<p>
The NDB API is a MySQL Cluster application interface that implements transactions. The NDB API consists of the following fundamental classes:<ul>
<li><a class="el" href="classNdb__cluster__connection.html" title="Represents a connection to a cluster of storage nodes.">Ndb_cluster_connection</a>, representing a connection to a cluster,</li><li><a class="el" href="classNdb.html" title="Represents the NDB kernel and is the main class of the NDB API.">Ndb</a> is the main class, representing a connection to a database,</li><li><a class="el" href="classNdbTransaction.html" title="Represents a transaction.">NdbTransaction</a> represents a transaction,</li><li><a class="el" href="classNdbOperation.html" title="Class of operations for use in transactions.">NdbOperation</a> represents an operation using a primary key,</li><li><a class="el" href="classNdbScanOperation.html" title="Class of scan operations for use in transactions.">NdbScanOperation</a> represents an operation performing a full table scan.</li><li><a class="el" href="classNdbIndexOperation.html" title="Class of index operations for use in transactions.">NdbIndexOperation</a> represents an operation using a unique hash index,</li><li><a class="el" href="classNdbIndexScanOperation.html" title="Class of scan operations for use to scan ordered index.">NdbIndexScanOperation</a> represents an operation performing a scan using an ordered index,</li><li><a class="el" href="classNdbRecAttr.html" title="Contains value of an attribute.">NdbRecAttr</a> represents an attribute value</li><li><a class="el" href="classNdbDictionary.html" title="Data dictionary class.">NdbDictionary</a> represents meta information about tables and attributes.</li></ul>
<p>
In addition, the NDB API defines a structure <a class="el" href="structNdbError.html" title="Contains error information.">NdbError</a>, which contains the specification for an error.<p>
There are also some auxiliary classes, which are listed in the class hierarchy.<p>
The main structure of an application program is as follows:<ol type=1>
<li>Connect to a cluster using the <a class="el" href="classNdb__cluster__connection.html" title="Represents a connection to a cluster of storage nodes.">Ndb_cluster_connection</a> object.</li><li>Initiate a database connection by constructing and initialising one or more <a class="el" href="classNdb.html" title="Represents the NDB kernel and is the main class of the NDB API.">Ndb</a> objects.</li><li>Define and execute transactions using the <a class="el" href="classNdbTransaction.html" title="Represents a transaction.">NdbTransaction</a> class.</li><li>Delete <a class="el" href="classNdb.html" title="Represents the NDB kernel and is the main class of the NDB API.">Ndb</a> objects.</li><li>Terminate the connection to the cluster (terminate instance of <a class="el" href="classNdb__cluster__connection.html" title="Represents a connection to a cluster of storage nodes.">Ndb_cluster_connection</a>).</li></ol>
<p>
The procedure for using transactions is as follows:<ol type=1>
<li>Start transaction (instantiate an <a class="el" href="classNdbTransaction.html" title="Represents a transaction.">NdbTransaction</a> object)</li><li>Add and define operations associated with the transaction using instances of one or more of the <a class="el" href="classNdbOperation.html" title="Class of operations for use in transactions.">NdbOperation</a>, <a class="el" href="classNdbScanOperation.html" title="Class of scan operations for use in transactions.">NdbScanOperation</a>, <a class="el" href="classNdbIndexOperation.html" title="Class of index operations for use in transactions.">NdbIndexOperation</a>, and <a class="el" href="classNdbIndexScanOperation.html" title="Class of scan operations for use to scan ordered index.">NdbIndexScanOperation</a> classes</li><li>Execute transaction (call <a class="el" href="classNdbTransaction.html#361d5a82078f86a5d18923f56d43cc84">NdbTransaction::execute()</a>)</li></ol>
<p>
The operation can be of two different types, <em>Commit</em> or <em>NoCommit</em>. If the operation is of type <em>NoCommit</em>, then the application program executes the operation part of a transaction, but without actually committing the transaction. After executing a <em>NoCommit</em> operation, the program can continue to add and define more operations to the transaction for later execution.<p>
If the operation is of type <em>Commit</em>, then the transaction is immediately committed. The transaction <em>must</em> be closed after it has been commited (event if commit fails), and no further addition or definition of operations for this transaction is allowed.<h2><a class="anchor" name="secSync">
Synchronous Transactions</a></h2>
Synchronous transactions are defined and executed as follows:<p>
<ol type=1>
<li>Start (create) the transaction, which is referenced by an <a class="el" href="classNdbTransaction.html" title="Represents a transaction.">NdbTransaction</a> object (typically created using <a class="el" href="classNdb.html#7e34bb5d8e3d878a54ebb7c0e6d0c5f1">Ndb::startTransaction()</a>). At this point, the transaction is only being defined, and is not yet sent to the NDB kernel.</li><li>Define operations and add them to the transaction, using one or more of<ul>
<li><a class="el" href="classNdbTransaction.html#2aeb211e54f84bd2de6cfb8fccec8166">NdbTransaction::getNdbOperation()</a></li><li><a class="el" href="classNdbTransaction.html#165fbac99710fd693485b16d073957dd">NdbTransaction::getNdbScanOperation()</a></li><li><a class="el" href="classNdbTransaction.html#4314de6305b86f4a3811ee97e7000f87">NdbTransaction::getNdbIndexOperation()</a></li><li><a class="el" href="classNdbTransaction.html#b199e982a860740bca8150801cddde94">NdbTransaction::getNdbIndexScanOperation()</a> along with the appropriate methods of the respective <a class="el" href="classNdbOperation.html" title="Class of operations for use in transactions.">NdbOperation</a> class (or one possiblt one or more of its subclasses). Note that the transaction has still not yet been sent to the NDB kernel.</li></ul>
</li><li>Execute the transaction, using the <a class="el" href="classNdbTransaction.html#361d5a82078f86a5d18923f56d43cc84">NdbTransaction::execute()</a> method.</li><li>Close the transaction (call <a class="el" href="classNdb.html#afbf5620c516bf18e0a3d3bacaf38e67">Ndb::closeTransaction()</a>).</li></ol>
<p>
For an example of this process, see the program listing in <a class="el" href="ndbapi_simple.cpp.html">ndbapi_simple.cpp</a>.<p>
To execute several parallel synchronous transactions, one can either use multiple <a class="el" href="classNdb.html" title="Represents the NDB kernel and is the main class of the NDB API.">Ndb</a> objects in several threads, or start multiple application programs.<h2><a class="anchor" name="secNdbOperations">
Operations</a></h2>
A <a class="el" href="classNdbTransaction.html" title="Represents a transaction.">NdbTransaction</a> consists of a list of operations, each of which is represented by an instance of <a class="el" href="classNdbOperation.html" title="Class of operations for use in transactions.">NdbOperation</a>, <a class="el" href="classNdbScanOperation.html" title="Class of scan operations for use in transactions.">NdbScanOperation</a>, <a class="el" href="classNdbIndexOperation.html" title="Class of index operations for use in transactions.">NdbIndexOperation</a>, or <a class="el" href="classNdbIndexScanOperation.html" title="Class of scan operations for use to scan ordered index.">NdbIndexScanOperation</a>.<p>
<h3>Single row operations</h3>
<p>
After the operation is created using <a class="el" href="classNdbTransaction.html#2aeb211e54f84bd2de6cfb8fccec8166">NdbTransaction::getNdbOperation()</a> (or <a class="el" href="classNdbTransaction.html#4314de6305b86f4a3811ee97e7000f87">NdbTransaction::getNdbIndexOperation()</a>), it is defined in the following three steps:<ol type=1>
<li>Define the standard operation type, using <a class="el" href="classNdbOperation.html#64aee1ff7083d96bfd66686c32b44c46">NdbOperation::readTuple()</a></li><li>Specify search conditions, using <a class="el" href="classNdbOperation.html#2839b64df3a181f6023fb36a9fe8ab74">NdbOperation::equal()</a></li><li>Specify attribute actions, using <a class="el" href="classNdbOperation.html#644b56e6e5dbe4d4cc414a7c1ec13cc4">NdbOperation::getValue()</a></li></ol>
<p>
Here are two brief examples illustrating this process. For the sake of brevity, we omit error handling.<p>
This first example uses an <a class="el" href="classNdbOperation.html" title="Class of operations for use in transactions.">NdbOperation</a>: <div class="fragment"><pre class="fragment">     <span class="comment">// 1. Retrieve table object</span>
     myTable= myDict-&gt;getTable(<span class="stringliteral">"MYTABLENAME"</span>);

     <span class="comment">// 2. Create</span>
     myOperation= myTransaction-&gt;getNdbOperation(myTable);
    
     <span class="comment">// 3. Define type of operation and lock mode</span>
     myOperation-&gt;readTuple(<a class="code" href="classNdbOperation.html#bb62acf3797243787ce5814417f455103b3e1f6d331193a0ff6aeb4831435890" title="Read with shared lock.">NdbOperation::LM_Read</a>);

     <span class="comment">// 4. Specify Search Conditions</span>
     myOperation-&gt;equal(<span class="stringliteral">"ATTR1"</span>, i);
    
     <span class="comment">// 5. Attribute Actions</span>
     myRecAttr= myOperation-&gt;getValue(<span class="stringliteral">"ATTR2"</span>, NULL);
</pre></div> For additional examples of this sort, see <a class="el" href="ndbapi_simple.cpp.html">ndbapi_simple.cpp</a>.<p>
The second example uses an <a class="el" href="classNdbIndexOperation.html" title="Class of index operations for use in transactions.">NdbIndexOperation</a>: <div class="fragment"><pre class="fragment">     <span class="comment">// 1. Retrieve index object</span>
     myIndex= myDict-&gt;getIndex(<span class="stringliteral">"MYINDEX"</span>, <span class="stringliteral">"MYTABLENAME"</span>);

     <span class="comment">// 2. Create</span>
     myOperation= myTransaction-&gt;getNdbIndexOperation(myIndex);

     <span class="comment">// 3. Define type of operation and lock mode</span>
     myOperation-&gt;readTuple(<a class="code" href="classNdbOperation.html#bb62acf3797243787ce5814417f455103b3e1f6d331193a0ff6aeb4831435890" title="Read with shared lock.">NdbOperation::LM_Read</a>);

     <span class="comment">// 4. Specify Search Conditions</span>
     myOperation-&gt;equal(<span class="stringliteral">"ATTR1"</span>, i);

     <span class="comment">// 5. Attribute Actions </span>
     myRecAttr = myOperation-&gt;getValue(<span class="stringliteral">"ATTR2"</span>, NULL);
</pre></div> Another example of this second type can be found in <a class="el" href="ndbapi_simple_index.cpp.html">ndbapi_simple_index.cpp</a>.<p>
We will now discuss in somewhat greater detail each step involved in the creation and use of synchronous transactions.<p>
<h4>Step 1: Define single row operation type</h4>
<p>
The following operation types are supported:<ol type=1>
<li><a class="el" href="classNdbOperation.html#1e06cf9bb1ce1c5357004c32b1e89b15">NdbOperation::insertTuple()</a> : inserts a non-existing tuple</li><li><a class="el" href="classNdbOperation.html#38211ca5fa0f8ca48fffe2e1d2dfe623">NdbOperation::writeTuple()</a> : updates an existing tuple if is exists, otherwise inserts a new tuple</li><li><a class="el" href="classNdbOperation.html#6c6466bb68499cb0e78b015b9dc28ac9">NdbOperation::updateTuple()</a> : updates an existing tuple</li><li><a class="el" href="classNdbOperation.html#7acba2e8fcab683e6829bbf6bd942c6c">NdbOperation::deleteTuple()</a> : deletes an existing tuple</li><li><a class="el" href="classNdbOperation.html#64aee1ff7083d96bfd66686c32b44c46">NdbOperation::readTuple()</a> : reads an existing tuple with specified lock mode</li></ol>
<p>
All of these operations operate on the unique tuple key. (When <a class="el" href="classNdbIndexOperation.html" title="Class of index operations for use in transactions.">NdbIndexOperation</a> is used then all of these operations operate on a defined unique hash index.)<p>
<dl class="note" compact><dt><b>Note:</b></dt><dd>If you want to define multiple operations within the same transaction, then you need to call <a class="el" href="classNdbTransaction.html#2aeb211e54f84bd2de6cfb8fccec8166">NdbTransaction::getNdbOperation()</a> or <a class="el" href="classNdbTransaction.html#4314de6305b86f4a3811ee97e7000f87">NdbTransaction::getNdbIndexOperation()</a> for each operation.</dd></dl>
<h4>Step 2: Specify Search Conditions</h4>
<p>
The search condition is used to select tuples. Search conditions are set using <a class="el" href="classNdbOperation.html#2839b64df3a181f6023fb36a9fe8ab74">NdbOperation::equal()</a>.<p>
<h4>Step 3: Specify Attribute Actions</h4>
<p>
Next, it is necessary to determine which attributes should be read or updated. It is important to remember that:<ul>
<li>Deletes can neither read nor set values, but only delete them</li><li>Reads can only read values</li><li>Updates can only set values Normally the attribute is identified by name, but it is also possible to use the attribute's identity to determine the attribute.</li></ul>
<p>
<a class="el" href="classNdbOperation.html#644b56e6e5dbe4d4cc414a7c1ec13cc4">NdbOperation::getValue()</a> returns an <a class="el" href="classNdbRecAttr.html" title="Contains value of an attribute.">NdbRecAttr</a> object containing the read value. To obtain the actual value, one of two methods can be used; the application can either<ul>
<li>use its own memory (passed through a pointer aValue) to <a class="el" href="classNdbOperation.html#644b56e6e5dbe4d4cc414a7c1ec13cc4">NdbOperation::getValue()</a>, or</li><li>receive the attribute value in an <a class="el" href="classNdbRecAttr.html" title="Contains value of an attribute.">NdbRecAttr</a> object allocated by the NDB API.</li></ul>
<p>
The <a class="el" href="classNdbRecAttr.html" title="Contains value of an attribute.">NdbRecAttr</a> object is released when <a class="el" href="classNdb.html#afbf5620c516bf18e0a3d3bacaf38e67">Ndb::closeTransaction()</a> is called. Thus, the application cannot reference this object following any subsequent call to <a class="el" href="classNdb.html#afbf5620c516bf18e0a3d3bacaf38e67">Ndb::closeTransaction()</a>. Attempting to read data from an <a class="el" href="classNdbRecAttr.html" title="Contains value of an attribute.">NdbRecAttr</a> object before calling <a class="el" href="classNdbTransaction.html#361d5a82078f86a5d18923f56d43cc84">NdbTransaction::execute()</a> yields an undefined result.<h3><a class="anchor" name="secScan">
Scan Operations</a></h3>
Scans are roughly the equivalent of SQL cursors, providing a means to preform high-speed row processing. A scan can be performed on either a table (using <a class="el" href="classNdbScanOperation.html">NdbScanOperation</a>) or an ordered index (by means of an <a class="el" href="classNdbIndexScanOperation.html">NdbIndexScanOperation</a>).<p>
Scan operations are characterised by the following:<ul>
<li>They can perform only reads (shared, exclusive or dirty)</li><li>They can potentially work with multiple rows</li><li>They can be used to update or delete multiple rows</li><li>They can operate on several nodes in parallel</li></ul>
<p>
After the operation is created using <a class="el" href="classNdbTransaction.html#165fbac99710fd693485b16d073957dd">NdbTransaction::getNdbScanOperation()</a> (or <a class="el" href="classNdbTransaction.html#b199e982a860740bca8150801cddde94">NdbTransaction::getNdbIndexScanOperation()</a>), it is carried out in the following three steps:<ol type=1>
<li>Define the standard operation type, using <a class="el" href="classNdbScanOperation.html#c8b2adf1a1e07663dc99b93dbab93dfd">NdbScanOperation::readTuples()</a></li><li>Specify search conditions, using <a class="el" href="classNdbScanFilter.html">NdbScanFilter</a> and/or <a class="el" href="classNdbIndexScanOperation.html#d4f76dda883ec09b922c13d76bc85d44">NdbIndexScanOperation::setBound()</a></li><li>Specify attribute actions, using <a class="el" href="classNdbOperation.html#644b56e6e5dbe4d4cc414a7c1ec13cc4">NdbOperation::getValue()</a></li><li>Executing the transaction, using <a class="el" href="classNdbTransaction.html#361d5a82078f86a5d18923f56d43cc84">NdbTransaction::execute()</a></li><li>Traversing the result set by means of succssive calls to <a class="el" href="classNdbScanOperation.html#1507839f1b36a707314f16b52c94b20b">NdbScanOperation::nextResult()</a></li></ol>
<p>
Here are two brief examples illustrating this process. Once again, in order to keep things relatively short and simple, we will forego any error handling.<p>
This first example performs a table scan, using an <a class="el" href="classNdbScanOperation.html" title="Class of scan operations for use in transactions.">NdbScanOperation</a>: <div class="fragment"><pre class="fragment">     <span class="comment">// 1. Retrieve table object</span>
     myTable= myDict-&gt;getTable(<span class="stringliteral">"MYTABLENAME"</span>);
    
     <span class="comment">// 2. Create</span>
     myOperation= myTransaction-&gt;getNdbScanOperation(myTable);
    
     <span class="comment">// 3. Define type of operation and lock mode</span>
     myOperation-&gt;readTuples(<a class="code" href="classNdbOperation.html#bb62acf3797243787ce5814417f455103b3e1f6d331193a0ff6aeb4831435890" title="Read with shared lock.">NdbOperation::LM_Read</a>);

     <span class="comment">// 4. Specify Search Conditions</span>
     <a class="code" href="classNdbScanFilter.html" title="A simple way to specify filters for scan operations.">NdbScanFilter</a> sf(myOperation);
     sf.begin(<a class="code" href="classNdbScanFilter.html#2054e0e6f52df029185c920cd6ca21227736be9ec3c435b32834390c4a646eed" title="(x1 OR x2 OR X3)">NdbScanFilter::OR</a>);
     sf.eq(0, i);   <span class="comment">// Return rows with column 0 equal to i or</span>
     sf.eq(1, i+1); <span class="comment">// column 1 equal to (i+1)</span>
     sf.end();

     <span class="comment">// 5. Attribute Actions</span>
     myRecAttr= myOperation-&gt;getValue(<span class="stringliteral">"ATTR2"</span>, NULL);
</pre></div><p>
Our second example uses an <a class="el" href="classNdbIndexScanOperation.html" title="Class of scan operations for use to scan ordered index.">NdbIndexScanOperation</a> to perform an index scan: <div class="fragment"><pre class="fragment">     <span class="comment">// 1. Retrieve index object</span>
     myIndex= myDict-&gt;getIndex(<span class="stringliteral">"MYORDEREDINDEX"</span>, <span class="stringliteral">"MYTABLENAME"</span>);

     <span class="comment">// 2. Create</span>
     myOperation= myTransaction-&gt;getNdbIndexScanOperation(myIndex);

     <span class="comment">// 3. Define type of operation and lock mode</span>
     myOperation-&gt;readTuples(<a class="code" href="classNdbOperation.html#bb62acf3797243787ce5814417f455103b3e1f6d331193a0ff6aeb4831435890" title="Read with shared lock.">NdbOperation::LM_Read</a>);

     <span class="comment">// 4. Specify Search Conditions</span>
     <span class="comment">// All rows with ATTR1 between i and (i+1)</span>
     myOperation-&gt;setBound(<span class="stringliteral">"ATTR1"</span>, <a class="code" href="classNdbIndexScanOperation.html#bd2e293842d11e99efcc57eaa2ec695cd9d0f1b50bbb55cf1e57771da5fd71c8" title="upper bound">NdbIndexScanOperation::BoundGE</a>, i);
     myOperation-&gt;setBound(<span class="stringliteral">"ATTR1"</span>, <a class="code" href="classNdbIndexScanOperation.html#bd2e293842d11e99efcc57eaa2ec695cdaea2544651fb1de0ee453b849a1c176" title="lower bound">NdbIndexScanOperation::BoundLE</a>, i+1);

     <span class="comment">// 5. Attribute Actions </span>
     myRecAttr = MyOperation-&gt;getValue(<span class="stringliteral">"ATTR2"</span>, NULL);
</pre></div><p>
Some additional discussion of each step required to perform a scan follows:<p>
<h4>Step 1: Define Scan Operation Type</h4>
<p>
It is important to remember that only a single operation is supported for each scan operation (<a class="el" href="classNdbScanOperation.html#c8b2adf1a1e07663dc99b93dbab93dfd">NdbScanOperation::readTuples()</a> or <a class="el" href="classNdbIndexScanOperation.html#b1ffa1a66c801adf1a736367e4f896d5">NdbIndexScanOperation::readTuples()</a>).<p>
<dl class="note" compact><dt><b>Note:</b></dt><dd>If you want to define multiple scan operations within the same transaction, then you need to call <a class="el" href="classNdbTransaction.html#165fbac99710fd693485b16d073957dd">NdbTransaction::getNdbScanOperation()</a> or <a class="el" href="classNdbTransaction.html#b199e982a860740bca8150801cddde94">NdbTransaction::getNdbIndexScanOperation()</a> separately for <b>each</b> operation.</dd></dl>
<h4>Step 2: Specify Search Conditions</h4>
<p>
The search condition is used to select tuples. If no search condition is specified, the scan will return all rows in the table.<p>
The search condition can be an <a class="el" href="classNdbScanFilter.html">NdbScanFilter</a> (which can be used on both <a class="el" href="classNdbScanOperation.html">NdbScanOperation</a> and <a class="el" href="classNdbIndexScanOperation.html">NdbIndexScanOperation</a>) or bounds which can only be used on index scans (<a class="el" href="classNdbIndexScanOperation.html#d4f76dda883ec09b922c13d76bc85d44">NdbIndexScanOperation::setBound()</a>). An index scan can use both <a class="el" href="classNdbScanFilter.html" title="A simple way to specify filters for scan operations.">NdbScanFilter</a> and bounds.<p>
<dl class="note" compact><dt><b>Note:</b></dt><dd>When <a class="el" href="classNdbScanFilter.html" title="A simple way to specify filters for scan operations.">NdbScanFilter</a> is used, each row is examined, whether or not it is actually returned. However, when using bounds, only rows within the bounds will be examined.</dd></dl>
<h4>Step 3: Specify Attribute Actions</h4>
<p>
Next, it is necessary to define which attributes should be read. As with transaction attributes, scan attributes are defined by name but it is also possible to use the attributes' identities to define attributes.<p>
As previously discussed (see <a class="el" href="index.html#secSync">Synchronous Transactions</a>), the value read is returned as an <a class="el" href="classNdbRecAttr.html" title="Contains value of an attribute.">NdbRecAttr</a> object by the <a class="el" href="classNdbOperation.html#644b56e6e5dbe4d4cc414a7c1ec13cc4">NdbOperation::getValue()</a> method.<p>
<h3>Using Scan to Update/Delete</h3>
<p>
Scanning can also be used to update or delete rows. This is performed by<ol type=1>
<li>Scanning using exclusive locks (using <a class="el" href="classNdbOperation.html#bb62acf3797243787ce5814417f455103e2072829a61fb6cf156e33fd7891e5c" title="Read with exclusive lock.">NdbOperation::LM_Exclusive</a>)</li><li>When iterating through the result set, for each row optionally calling either <a class="el" href="classNdbScanOperation.html#c4fae6a089d87d69385ff859517ba190">NdbScanOperation::updateCurrentTuple()</a> or <a class="el" href="classNdbScanOperation.html#6d76ccfea4566d6cb4a7ecbd2858df58">NdbScanOperation::deleteCurrentTuple()</a></li><li>(If performing <a class="el" href="classNdbScanOperation.html#c4fae6a089d87d69385ff859517ba190">NdbScanOperation::updateCurrentTuple()</a>:) Setting new values for records simply by using <a class="el" href="classNdbOperation.html#e6fd36220eca78873d1d9b59539ab192">NdbOperation::setValue()</a>. <a class="el" href="classNdbOperation.html#2839b64df3a181f6023fb36a9fe8ab74">NdbOperation::equal()</a> should <em>not</em> be called in such cases, as the primary key is retrieved from the scan.</li></ol>
<p>
<dl class="note" compact><dt><b>Note:</b></dt><dd>The actual update or delete will not be performed until the next call to <a class="el" href="classNdbTransaction.html#361d5a82078f86a5d18923f56d43cc84">NdbTransaction::execute()</a>, just as with single row operations. <a class="el" href="classNdbTransaction.html#361d5a82078f86a5d18923f56d43cc84">NdbTransaction::execute()</a> also must be called before any locks are released; see <a class="el" href="index.html#secScanLocks">Lock handling with scans</a> for more information.</dd></dl>
<h4>Features Specific to Index Scans</h4>
<p>
When performing an index scan, it is possible to scan only a subset of a table using <a class="el" href="classNdbIndexScanOperation.html#d4f76dda883ec09b922c13d76bc85d44">NdbIndexScanOperation::setBound()</a>. In addition, result sets can be sorted in either ascending or descending order, using <a class="el" href="classNdbIndexScanOperation.html#b1ffa1a66c801adf1a736367e4f896d5">NdbIndexScanOperation::readTuples()</a>. Note that rows are returned unordered by default, that is, unless <em>sorted</em> is set to <b>true</b>. It is also important to note that, when using <a class="el" href="classNdbIndexScanOperation.html#bd2e293842d11e99efcc57eaa2ec695cbcc9b5999344bf13c65c82e818a0044c" title="equality">NdbIndexScanOperation::BoundEQ</a> on a partition key, only fragments containing rows will actually be scanned.<p>
<dl class="note" compact><dt><b>Note:</b></dt><dd>When performing a sorted scan, any value passed as the <a class="el" href="classNdbIndexScanOperation.html#b1ffa1a66c801adf1a736367e4f896d5">NdbIndexScanOperation::readTuples()</a> method's <code>parallel</code> argument will be ignored and maximum parallelism will be used instead. In other words, all fragments which it is possible to scan will be scanned simultaneously and in parallel in such cases.</dd></dl>
<h3><a class="anchor" name="secScanLocks">
Lock handling with scans</a></h3>
Performing scans on either a tables or an index has the potential return a great many records; however, <a class="el" href="classNdb.html" title="Represents the NDB kernel and is the main class of the NDB API.">Ndb</a> will lock only a predetermined number of rows per fragment at a time. How many rows will be locked per fragment is controlled by the <em>batch</em> parameter passed to <a class="el" href="classNdbScanOperation.html#c8b2adf1a1e07663dc99b93dbab93dfd">NdbScanOperation::readTuples()</a>.<p>
In order to allow the application to handle how locks are released, <a class="el" href="classNdbScanOperation.html#1507839f1b36a707314f16b52c94b20b">NdbScanOperation::nextResult()</a> has a Boolean parameter <em>fetch_allow</em>. If <a class="el" href="classNdbScanOperation.html#1507839f1b36a707314f16b52c94b20b">NdbScanOperation::nextResult()</a> is called with <em>fetch_allow</em> equal to <b>false</b>, then no locks may be released as result of the function call. Otherwise the locks for the current batch may be released.<p>
This next example shows a scan delete that handle locks in an efficient manner. For the sake of brevity, we omit error-handling. <div class="fragment"><pre class="fragment">     <span class="keywordtype">int</span> check;

     <span class="comment">// Outer loop for each batch of rows</span>
     <span class="keywordflow">while</span>((check = MyScanOperation-&gt;nextResult(<span class="keyword">true</span>)) == 0)
     {
       <span class="keywordflow">do</span>
       {
         <span class="comment">// Inner loop for each row within batch</span>
         MyScanOperation-&gt;deleteCurrentTuple();
       } <span class="keywordflow">while</span>((check = MyScanOperation-&gt;nextResult(<span class="keyword">false</span>)) == 0);

       <span class="comment">// When no more rows in batch, exeute all defined deletes       </span>
       MyTransaction-&gt;execute(NoCommit);
     }
</pre></div><p>
See <a class="el" href="ndbapi_scan.cpp.html">ndbapi_scan.cpp</a> for a more complete example of a scan.<h2><a class="anchor" name="secError">
Error Handling</a></h2>
Errors can occur either when operations making up a transaction are being defined, or when the transaction is actually being executed. Catching and handling either sort of error requires testing the value returned by <a class="el" href="classNdbTransaction.html#361d5a82078f86a5d18923f56d43cc84">NdbTransaction::execute()</a>, and then, if an error is indicated (that is, if this value is equal to -1), using the following two methods in order to identify the error's type and location:<p>
<ul>
<li><a class="el" href="classNdbTransaction.html#6b2b1b7e05d9cc5ecd958fc49a17a109">NdbTransaction::getNdbErrorOperation()</a> returns a reference to the operation causing the most recent error.</li><li><a class="el" href="classNdbTransaction.html#dc51806a1bc3b7a727d54e05c71d6f22">NdbTransaction::getNdbErrorLine()</a> yields the method number of the erroneous method in the operation.</li></ul>
<p>
This short example illustrates how to detect an error and to use these two methods to identify it:<p>
<div class="fragment"><pre class="fragment">     theTransaction = theNdb-&gt;startTransaction();
     theOperation = theTransaction-&gt;getNdbOperation(<span class="stringliteral">"TEST_TABLE"</span>);
     <span class="keywordflow">if</span> (theOperation == NULL) <span class="keywordflow">goto</span> error;
     theOperation-&gt;readTuple(<a class="code" href="classNdbOperation.html#bb62acf3797243787ce5814417f455103b3e1f6d331193a0ff6aeb4831435890" title="Read with shared lock.">NdbOperation::LM_Read</a>);
     theOperation-&gt;setValue(<span class="stringliteral">"ATTR_1"</span>, at1);
     theOperation-&gt;setValue(<span class="stringliteral">"ATTR_2"</span>, at1);  <span class="comment">//  Error occurs here</span>
     theOperation-&gt;setValue(<span class="stringliteral">"ATTR_3"</span>, at1);
     theOperation-&gt;setValue(<span class="stringliteral">"ATTR_4"</span>, at1);
    
     <span class="keywordflow">if</span> (theTransaction-&gt;execute(Commit) == -1) {
       errorLine = theTransaction-&gt;getNdbErrorLine();
       errorOperation = theTransaction-&gt;getNdbErrorOperation();
     }
</pre></div><p>
Here <code>errorLine</code> will be 3, as the error occurred in the third method called on the <a class="el" href="classNdbOperation.html" title="Class of operations for use in transactions.">NdbOperation</a> object (in this case, <code>theOperation</code>); if the result of <a class="el" href="classNdbTransaction.html#dc51806a1bc3b7a727d54e05c71d6f22">NdbTransaction::getNdbErrorLine()</a> is 0, this means that the error occurred when the operations were executed. In this example, <code>errorOperation</code> will be a pointer to the <code>theOperation</code> object. The <a class="el" href="classNdbTransaction.html#f4af91ca21b97c4fe6256a18903020fc">NdbTransaction::getNdbError()</a> method returns an <a class="el" href="structNdbError.html" title="Contains error information.">NdbError</a> object providing information about the error.<p>
<dl class="note" compact><dt><b>Note:</b></dt><dd>Transactions are <b>not</b> automatically closed when an error occurs. Call <a class="el" href="classNdb.html#afbf5620c516bf18e0a3d3bacaf38e67">Ndb::closeTransaction()</a> to close the transaction.</dd></dl>
One recommended way to handle a transaction failure (i.e. an error is reported) is to:<ol type=1>
<li>Rollback transaction (call <a class="el" href="classNdbTransaction.html#361d5a82078f86a5d18923f56d43cc84">NdbTransaction::execute()</a> with a special parameter)</li><li>Close transaction (call NdbTransaction::closeTransaction())</li><li>If the error was temporary, attempt to restart the transaction</li></ol>
<p>
Several errors can occur when a transaction contains multiple operations which are simultaneously executed. In this case the application has to go through all operations and query their <a class="el" href="structNdbError.html" title="Contains error information.">NdbError</a> objects to find out what really happened.<p>
It is also important to note that errors can occur even when a commit is reported as successful. In order to handle such situations, the NDB API provides an additional <a class="el" href="classNdbTransaction.html#a69f5c397309c187f35adfe14a9345c9">NdbTransaction::commitStatus()</a> method to check the transactions's commit status. </div>
<hr>
<address>
<small>
<center>
Documentation generated Sun Apr 20 06:25:31 2008 from mysql source files.<br>
&copy; 2003-2004 
<a href="http://www.mysql.com">MySQL AB</a>
<br>
</center>
</small></address>
</body>
</html>