Description:
The error handling in the ndbapi_scan example appears to be
broken. From scan_delete() in ndbapi_scan.cpp:
/**
* start of loop: nextResult(true) means that "parallelism" number of
* rows are fetched from NDB and cached in NDBAPI
*/
while((check = myScanOp->nextResult(true)) == 0){
do
{
if (myScanOp->deleteCurrentTuple() != 0)
{
std::cout << myTrans->getNdbError().message << std::endl;
myNdb->closeTransaction(myTrans);
return -1;
}
deletedRows++;
/**
* nextResult(false) means that the records
* cached in the NDBAPI are modified before
* fetching more rows from NDB.
*/
} while((check = myScanOp->nextResult(false)) == 0);
/**
* Commit when all cached tuple have been marked for deletion
*/
if(check != -1)
{
check = myTrans->execute(NdbTransaction::Commit);
}
if(check == -1)
{
/**
* Create a new transaction, while keeping scan open
*/
check = myTrans->restart(); // [1]
}
/**
* Check for errors
*/
err = myTrans->getNdbError();
if(check == -1) // [2]
{
if(err.status == NdbError::TemporaryError) // [3]
{
std::cout << myTrans->getNdbError().message << std::endl;
myNdb->closeTransaction(myTrans);
milliSleep(50);
continue; // [4]
}
}
/**
* End of loop
*/
From NdbTransaction.hpp:
* @note This method can only be called _directly_ after commit
* and only if commit is successful
*/
int restart();
[1] If the execute(Commit) failed the restart() should not have been
called.
[2] If restart() return 0 the error checking will not see that there
was an error in the first place since 'check' have been set to 0
again.
[3] Why only check for temporary errors?
[4] This will continue the loop and check for nextResult() in an
operation belonging to a transaction just closed. Is the result of
this operation known? I fail to find this information in
NdbScanOperation.hpp anyway. (run.3.txt in bug#39572 looks like
it got locked up somewhere after this call)
How to repeat:
Read the example and the internal description in NdbTransaction.hpp
Suggested fix:
Fix the example.