Sophie

Sophie

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

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>ndbapi_retries.cpp</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><a class="anchor" name="ndbapi_retries.cpp">ndbapi_retries.cpp </a></h1><div class="fragment"><pre class="fragment"><span class="comment">/* Copyright (C) 2003 MySQL AB</span>
<span class="comment"></span>
<span class="comment">   This program is free software; you can redistribute it and/or modify</span>
<span class="comment">   it under the terms of the GNU General Public License as published by</span>
<span class="comment">   the Free Software Foundation; version 2 of the License.</span>
<span class="comment"></span>
<span class="comment">   This program is distributed in the hope that it will be useful,</span>
<span class="comment">   but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="comment">   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span>
<span class="comment">   GNU General Public License for more details.</span>
<span class="comment"></span>
<span class="comment">   You should have received a copy of the GNU General Public License</span>
<span class="comment">   along with this program; if not, write to the Free Software</span>
<span class="comment">   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */</span>

<span class="comment">// </span>
<span class="comment">//  ndbapi_retries.cpp: Error handling and transaction retries</span>
<span class="comment">//</span>
<span class="comment">//  Execute ndbapi_simple to create the table "MYTABLENAME"</span>
<span class="comment">//  before executing this program.</span>
<span class="comment">//</span>
<span class="comment">//  There are many ways to program using the NDB API.  In this example</span>
<span class="comment">//  we execute two inserts in the same transaction using </span>
<span class="comment">//  NdbConnection::execute(NoCommit).</span>
<span class="comment">// </span>
<span class="comment">//  Transaction failing is handled by re-executing the transaction</span>
<span class="comment">//  in case of non-permanent transaction errors.</span>
<span class="comment">//  Application errors (i.e. errors at points marked with APIERROR) </span>
<span class="comment">//  should be handled by the application programmer.</span>

<span class="preprocessor">#include &lt;NdbApi.hpp&gt;</span>

<span class="comment">// Used for cout</span>
<span class="preprocessor">#include &lt;iostream&gt;</span>  

<span class="comment">// Used for sleep (use your own version of sleep)</span>
<span class="preprocessor">#include &lt;unistd.h&gt;</span>
<span class="preprocessor">#define TIME_TO_SLEEP_BETWEEN_TRANSACTION_RETRIES 1</span>
<span class="preprocessor"></span>
<span class="comment">//</span>
<span class="comment">//  APIERROR prints an NdbError object</span>
<span class="comment">//</span>
<span class="preprocessor">#define APIERROR(error) \</span>
<span class="preprocessor">  { std::cout &lt;&lt; "API ERROR: " &lt;&lt; error.code &lt;&lt; " " &lt;&lt; error.message \</span>
<span class="preprocessor">              &lt;&lt; std::endl \</span>
<span class="preprocessor">              &lt;&lt; "           " &lt;&lt; "Status: " &lt;&lt; error.status \</span>
<span class="preprocessor">              &lt;&lt; ", Classification: " &lt;&lt; error.classification &lt;&lt; std::endl\</span>
<span class="preprocessor">              &lt;&lt; "           " &lt;&lt; "File: " &lt;&lt; __FILE__ \</span>
<span class="preprocessor">              &lt;&lt; " (Line: " &lt;&lt; __LINE__ &lt;&lt; ")" &lt;&lt; std::endl \</span>
<span class="preprocessor">              ; \</span>
<span class="preprocessor">  }</span>
<span class="preprocessor"></span>
<span class="comment">//</span>
<span class="comment">//  TRANSERROR prints all error info regarding an NdbTransaction</span>
<span class="comment">//</span>
<span class="preprocessor">#define TRANSERROR(ndbTransaction) \</span>
<span class="preprocessor">  { NdbError error = ndbTransaction-&gt;getNdbError(); \</span>
<span class="preprocessor">    std::cout &lt;&lt; "TRANS ERROR: " &lt;&lt; error.code &lt;&lt; " " &lt;&lt; error.message \</span>
<span class="preprocessor">              &lt;&lt; std::endl \</span>
<span class="preprocessor">              &lt;&lt; "           " &lt;&lt; "Status: " &lt;&lt; error.status \</span>
<span class="preprocessor">              &lt;&lt; ", Classification: " &lt;&lt; error.classification &lt;&lt; std::endl \</span>
<span class="preprocessor">              &lt;&lt; "           " &lt;&lt; "File: " &lt;&lt; __FILE__ \</span>
<span class="preprocessor">              &lt;&lt; " (Line: " &lt;&lt; __LINE__ &lt;&lt; ")" &lt;&lt; std::endl \</span>
<span class="preprocessor">              ; \</span>
<span class="preprocessor">    printTransactionError(ndbTransaction); \</span>
<span class="preprocessor">  }</span>
<span class="preprocessor"></span>
<span class="keywordtype">void</span> printTransactionError(<a class="code" href="classNdbTransaction.html" title="Represents a transaction.">NdbTransaction</a> *ndbTransaction) {
  <span class="keyword">const</span> <a class="code" href="classNdbOperation.html" title="Class of operations for use in transactions.">NdbOperation</a> *ndbOp = NULL;
  <span class="keywordtype">int</span> i=0;

  <span class="comment">/****************************************************************</span>
<span class="comment">   * Print NdbError object of every operations in the transaction *</span>
<span class="comment">   ****************************************************************/</span>
  <span class="keywordflow">while</span> ((ndbOp = ndbTransaction-&gt;<a class="code" href="classNdbTransaction.html#cc45eb0b457f25f0615667a16cc44f73">getNextCompletedOperation</a>(ndbOp)) != NULL) {
    <a class="code" href="structNdbError.html" title="Contains error information.">NdbError</a> error = ndbOp-&gt;<a class="code" href="classNdbOperation.html#9e9aa90dcdbdc02066f3b386ebb79d04">getNdbError</a>();
    std::cout &lt;&lt; <span class="stringliteral">"           OPERATION "</span> &lt;&lt; i+1 &lt;&lt; <span class="stringliteral">": "</span> 
        &lt;&lt; error.<a class="code" href="structNdbError.html#87429c24aeeafdee05f41051ba0f2160">code</a> &lt;&lt; <span class="stringliteral">" "</span> &lt;&lt; error.<a class="code" href="structNdbError.html#59d98203577586394c30cdb01a270c2c">message</a> &lt;&lt; std::endl
        &lt;&lt; <span class="stringliteral">"           Status: "</span> &lt;&lt; error.<a class="code" href="structNdbError.html#f4af76b35a92ccebbb814705578e74e9">status</a> 
        &lt;&lt; <span class="stringliteral">", Classification: "</span> &lt;&lt; error.<a class="code" href="structNdbError.html#bc9a4841feb45bb8ca5fdaa8e14d20d6">classification</a> &lt;&lt; std::endl;
    i++;
  }
}


<span class="comment">//</span>
<span class="comment">//  Example insert</span>
<span class="comment">//  @param myNdb          Ndb object representing NDB Cluster</span>
<span class="comment">//  @param myTransaction  NdbTransaction used for transaction</span>
<span class="comment">//  @param myTable        Table to insert into</span>
<span class="comment">//  @param error          NdbError object returned in case of errors</span>
<span class="comment">//  @return -1 in case of failures, 0 otherwise</span>
<span class="comment">//</span>
<span class="keywordtype">int</span> insert(<span class="keywordtype">int</span> transactionId, <a class="code" href="classNdbTransaction.html" title="Represents a transaction.">NdbTransaction</a>* myTransaction,
     <span class="keyword">const</span> <a class="code" href="classNdbDictionary_1_1Table.html" title="Represents a table in NDB Cluster.">NdbDictionary::Table</a> *myTable) {
  <a class="code" href="classNdbOperation.html" title="Class of operations for use in transactions.">NdbOperation</a>   *myOperation;          <span class="comment">// For other operations</span>

  myOperation = myTransaction-&gt;<a class="code" href="classNdbTransaction.html#2aeb211e54f84bd2de6cfb8fccec8166">getNdbOperation</a>(myTable);
  <span class="keywordflow">if</span> (myOperation == NULL) <span class="keywordflow">return</span> -1;
  
  <span class="keywordflow">if</span> (myOperation-&gt;<a class="code" href="classNdbOperation.html#1e06cf9bb1ce1c5357004c32b1e89b15">insertTuple</a>() ||  
      myOperation-&gt;<a class="code" href="classNdbOperation.html#2839b64df3a181f6023fb36a9fe8ab74">equal</a>(<span class="stringliteral">"ATTR1"</span>, transactionId) ||
      myOperation-&gt;<a class="code" href="classNdbOperation.html#e6fd36220eca78873d1d9b59539ab192">setValue</a>(<span class="stringliteral">"ATTR2"</span>, transactionId)) {
    APIERROR(myOperation-&gt;<a class="code" href="classNdbOperation.html#9e9aa90dcdbdc02066f3b386ebb79d04">getNdbError</a>());
    exit(-1);
  }

  <span class="keywordflow">return</span> myTransaction-&gt;<a class="code" href="classNdbTransaction.html#361d5a82078f86a5d18923f56d43cc84">execute</a>(<a class="code" href="classNdbTransaction.html#2d2a5911b91e5cf78da970a1e97f7e3ed2041cab47f522aa4365d70a49267d6d">NdbTransaction::NoCommit</a>);
}


<span class="comment">//</span>
<span class="comment">//  Execute function which re-executes (tries 10 times) the transaction </span>
<span class="comment">//  if there are temporary errors (e.g. the NDB Cluster is overloaded).</span>
<span class="comment">//  @return -1 failure, 1 success</span>
<span class="comment">//</span>
<span class="keywordtype">int</span> executeInsertTransaction(<span class="keywordtype">int</span> transactionId, <a class="code" href="classNdb.html" title="Represents the NDB kernel and is the main class of the NDB API.">Ndb</a>* myNdb,
           <span class="keyword">const</span> <a class="code" href="classNdbDictionary_1_1Table.html" title="Represents a table in NDB Cluster.">NdbDictionary::Table</a> *myTable) {
  <span class="keywordtype">int</span> result = 0;                       <span class="comment">// No result yet</span>
  <span class="keywordtype">int</span> noOfRetriesLeft = 10;
  <a class="code" href="classNdbTransaction.html" title="Represents a transaction.">NdbTransaction</a>   *myTransaction;         <span class="comment">// For other transactions</span>
  <a class="code" href="structNdbError.html" title="Contains error information.">NdbError</a> ndberror;
  
  <span class="keywordflow">while</span> (noOfRetriesLeft &gt; 0 &amp;&amp; !result) {
    
    <span class="comment">/*********************************</span>
<span class="comment">     * Start and execute transaction *</span>
<span class="comment">     *********************************/</span>
    myTransaction = myNdb-&gt;<a class="code" href="classNdb.html#7e34bb5d8e3d878a54ebb7c0e6d0c5f1">startTransaction</a>();
    <span class="keywordflow">if</span> (myTransaction == NULL) {
      APIERROR(myNdb-&gt;<a class="code" href="classNdb.html#80b53a037bb2e93b3cd6830eda58643a">getNdbError</a>());
      ndberror = myNdb-&gt;<a class="code" href="classNdb.html#80b53a037bb2e93b3cd6830eda58643a">getNdbError</a>();
      result = -1;  <span class="comment">// Failure</span>
    } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (insert(transactionId, myTransaction, myTable) || 
         insert(10000+transactionId, myTransaction, myTable) ||
         myTransaction-&gt;<a class="code" href="classNdbTransaction.html#361d5a82078f86a5d18923f56d43cc84">execute</a>(<a class="code" href="classNdbTransaction.html#2d2a5911b91e5cf78da970a1e97f7e3ecaba2931e541dd138044b61f38918391" title="Execute and try to commit the transaction.">NdbTransaction::Commit</a>)) {
      TRANSERROR(myTransaction);
      ndberror = myTransaction-&gt;<a class="code" href="classNdbTransaction.html#f4af91ca21b97c4fe6256a18903020fc">getNdbError</a>();
      result = -1;  <span class="comment">// Failure</span>
    } <span class="keywordflow">else</span> {
      result = 1;   <span class="comment">// Success</span>
    }

    <span class="comment">/**********************************</span>
<span class="comment">     * If failure, then analyze error *</span>
<span class="comment">     **********************************/</span>
    <span class="keywordflow">if</span> (result == -1) {                 
      <span class="keywordflow">switch</span> (ndberror.status) {
      <span class="keywordflow">case</span> <a class="code" href="structNdbError.html#77140bdb323bd821bd517639ad458618eda60d921a6f3415692bc163084cc326">NdbError::Success</a>:
  <span class="keywordflow">break</span>;
      <span class="keywordflow">case</span> <a class="code" href="structNdbError.html#77140bdb323bd821bd517639ad4586189d6a4af4ffaf1aed83fdf29ef2c47227">NdbError::TemporaryError</a>:
  std::cout &lt;&lt; <span class="stringliteral">"Retrying transaction..."</span> &lt;&lt; std::endl;
  sleep(TIME_TO_SLEEP_BETWEEN_TRANSACTION_RETRIES);
  --noOfRetriesLeft;
  result = 0;   <span class="comment">// No completed transaction yet</span>
  <span class="keywordflow">break</span>;
  
      <span class="keywordflow">case</span> <a class="code" href="structNdbError.html#77140bdb323bd821bd517639ad45861895ee56680dca939e370f27de09c92f4c">NdbError::UnknownResult</a>:
      <span class="keywordflow">case</span> <a class="code" href="structNdbError.html#77140bdb323bd821bd517639ad458618f39e2cb3839afe2ccecc9b44905b3d89">NdbError::PermanentError</a>:
  std::cout &lt;&lt; <span class="stringliteral">"No retry of transaction..."</span> &lt;&lt; std::endl;
  result = -1;  <span class="comment">// Permanent failure</span>
  <span class="keywordflow">break</span>;
      }
    }

    <span class="comment">/*********************</span>
<span class="comment">     * Close transaction *</span>
<span class="comment">     *********************/</span>
    <span class="keywordflow">if</span> (myTransaction != NULL) {
      myNdb-&gt;<a class="code" href="classNdb.html#afbf5620c516bf18e0a3d3bacaf38e67">closeTransaction</a>(myTransaction);
    }
  }

  <span class="keywordflow">if</span> (result != 1) exit(-1);
  <span class="keywordflow">return</span> result;
}


<span class="keywordtype">int</span> main()
{
  ndb_init();

  <a class="code" href="classNdb__cluster__connection.html" title="Represents a connection to a cluster of storage nodes.">Ndb_cluster_connection</a> *cluster_connection=
    <span class="keyword">new</span> <a class="code" href="classNdb__cluster__connection.html" title="Represents a connection to a cluster of storage nodes.">Ndb_cluster_connection</a>(); <span class="comment">// Object representing the cluster</span>

  <span class="keywordtype">int</span> r= cluster_connection-&gt;<a class="code" href="classNdb__cluster__connection.html#1c1523c47bc56f17beb5c7e9124f7f47">connect</a>(5 <span class="comment">/* retries               */</span>,
             3 <span class="comment">/* delay between retries */</span>,
             1 <span class="comment">/* verbose               */</span>);
  <span class="keywordflow">if</span> (r &gt; 0)
  {
    std::cout
      &lt;&lt; <span class="stringliteral">"Cluster connect failed, possibly resolved with more retries.\n"</span>;
    exit(-1);
  }
  <span class="keywordflow">else</span> <span class="keywordflow">if</span> (r &lt; 0)
  {
    std::cout
      &lt;&lt; <span class="stringliteral">"Cluster connect failed.\n"</span>;
    exit(-1);
  }
             
  <span class="keywordflow">if</span> (cluster_connection-&gt;<a class="code" href="classNdb__cluster__connection.html#02f01d4e1dba63679a4796838e3c3c7a">wait_until_ready</a>(30,30))
  {
    std::cout &lt;&lt; <span class="stringliteral">"Cluster was not ready within 30 secs."</span> &lt;&lt; std::endl;
    exit(-1);
  }

  <a class="code" href="classNdb.html" title="Represents the NDB kernel and is the main class of the NDB API.">Ndb</a>* myNdb= <span class="keyword">new</span> <a class="code" href="classNdb.html" title="Represents the NDB kernel and is the main class of the NDB API.">Ndb</a>( cluster_connection,
           <span class="stringliteral">"TEST_DB_1"</span> );  <span class="comment">// Object representing the database</span>
  
  <span class="keywordflow">if</span> (myNdb-&gt;<a class="code" href="classNdb.html#b938638f0ced10e31ab67b3a80901270">init</a>() == -1) {
    APIERROR(myNdb-&gt;<a class="code" href="classNdb.html#80b53a037bb2e93b3cd6830eda58643a">getNdbError</a>());
    exit(-1);
  }

  <span class="keyword">const</span> <a class="code" href="classNdbDictionary_1_1Dictionary.html" title="Dictionary for defining and retreiving meta data.">NdbDictionary::Dictionary</a>* myDict= myNdb-&gt;<a class="code" href="classNdb.html#f27ca0f4e5c074211252a7c83060a3a4">getDictionary</a>();
  <span class="keyword">const</span> <a class="code" href="classNdbDictionary_1_1Table.html" title="Represents a table in NDB Cluster.">NdbDictionary::Table</a> *myTable= myDict-&gt;<a class="code" href="classNdbDictionary_1_1Dictionary.html#1a30b1bb5fa164113cb839eed64eb3b6">getTable</a>(<span class="stringliteral">"MYTABLENAME"</span>);
  <span class="keywordflow">if</span> (myTable == NULL)
  {
    APIERROR(myDict-&gt;<a class="code" href="classNdbDictionary_1_1Dictionary.html#0af68ea9b273172b46528ee1bd806f71">getNdbError</a>());
    <span class="keywordflow">return</span> -1;
  }
  <span class="comment">/************************************</span>
<span class="comment">   * Execute some insert transactions *</span>
<span class="comment">   ************************************/</span>
  <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 10000; i &lt; 20000; i++) {
    executeInsertTransaction(i, myNdb, myTable);
  }
  
  <span class="keyword">delete</span> myNdb;
  <span class="keyword">delete</span> cluster_connection;

  ndb_end(0);
  <span class="keywordflow">return</span> 0;
}
</pre></div> </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>