ndb_async1.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:19k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. //#define DEBUG_ON
  14. #include "userInterface.h"
  15. #include "macros.h"
  16. #include "ndb_schema.hpp"
  17. #include "ndb_error.hpp"
  18. #include <NdbApi.hpp>
  19. inline
  20. NdbConnection *
  21. startTransaction(Ndb * pNDB, 
  22.  ServerId inServerId, 
  23.  const SubscriberNumber inNumber){
  24.   
  25.   const int keyDataLenBytes    = sizeof(ServerId)+SUBSCRIBER_NUMBER_LENGTH;
  26.   const int keyDataLen_64Words = keyDataLenBytes >> 3;
  27.   Uint64 keyDataBuf[keyDataLen_64Words+1]; // The "+1" is for rounding...
  28.   
  29.   char     * keyDataBuf_charP = (char *)&keyDataBuf[0];
  30.   Uint32  * keyDataBuf_wo32P = (Uint32 *)&keyDataBuf[0];
  31.   
  32.   // Server Id comes first
  33.   keyDataBuf_wo32P[0] = inServerId;
  34.   // Then subscriber number
  35.   memcpy(&keyDataBuf_charP[sizeof(ServerId)], inNumber, 
  36.  SUBSCRIBER_NUMBER_LENGTH);
  37.   return pNDB->startTransaction(0, keyDataBuf_charP, keyDataLenBytes);
  38. }
  39. void T1_Callback(int result, NdbConnection * pCon, void * threadData);
  40. void T2_Callback(int result, NdbConnection * pCon, void * threadData);
  41. void T3_Callback_1(int result, NdbConnection * pCon, void * threadData);
  42. void T3_Callback_2(int result, NdbConnection * pCon, void * threadData);
  43. void T3_Callback_3(int result, NdbConnection * pCon, void * threadData);
  44. void T4_Callback_1(int result, NdbConnection * pCon, void * threadData);
  45. void T4_Callback_2(int result, NdbConnection * pCon, void * threadData);
  46. void T4_Callback_3(int result, NdbConnection * pCon, void * threadData);
  47. void T5_Callback_1(int result, NdbConnection * pCon, void * threadData);
  48. void T5_Callback_2(int result, NdbConnection * pCon, void * threadData);
  49. void T5_Callback_3(int result, NdbConnection * pCon, void * threadData);
  50. /**
  51.  * Transaction 1 - T1 
  52.  *
  53.  * Update location and changed by/time on a subscriber
  54.  *
  55.  * Input: 
  56.  *   SubscriberNumber,
  57.  *   Location,
  58.  *   ChangedBy,
  59.  *   ChangedTime
  60.  *
  61.  * Output:
  62.  */
  63. void
  64. start_T1(Ndb * pNDB, ThreadData * td){
  65.   DEBUG2("T1(%.*s): - Startingn", SUBSCRIBER_NUMBER_LENGTH, 
  66.  td->transactionData.number); 
  67.   int check;
  68.   NdbConnection * pCON = pNDB->startTransaction();
  69.   if (pCON != NULL) {
  70.     NdbOperation *MyOp = pCON->getNdbOperation(SUBSCRIBER_TABLE);
  71.     if (MyOp != NULL) {  
  72.       MyOp->updateTuple();  
  73.       MyOp->equal(IND_SUBSCRIBER_NUMBER, 
  74.   td->transactionData.number);
  75.       MyOp->setValue(IND_SUBSCRIBER_LOCATION, 
  76.      (char *)&td->transactionData.location);
  77.       MyOp->setValue(IND_SUBSCRIBER_CHANGED_BY, 
  78.      td->transactionData.changed_by);
  79.       MyOp->setValue(IND_SUBSCRIBER_CHANGED_TIME, 
  80.      td->transactionData.changed_time);
  81.       pCON->executeAsynchPrepare( Commit , T1_Callback, td);
  82.     } else {
  83.       CHECK_NULL(MyOp, "T1: getNdbOperation", pCON);
  84.     }//if
  85.   } else {
  86.     error_handler("T1-1: startTranscation", 
  87.   pNDB->getNdbErrorString(), 
  88.   pNDB->getNdbError());
  89.   }//if
  90. }
  91. void
  92. T1_Callback(int result, NdbConnection * pCON, void * threadData){
  93.   ThreadData * td = (ThreadData *)threadData;
  94.   
  95.   DEBUG2("T1(%.*s): - Completingn", SUBSCRIBER_NUMBER_LENGTH, 
  96.  td->transactionData.number); 
  97.   CHECK_MINUS_ONE(result, "T1: Commit", 
  98.   pCON);
  99.   td->pNDB->closeTransaction(pCON);
  100.   complete_T1(td);
  101. }
  102. /**
  103.  * Transaction 2 - T2
  104.  *
  105.  * Read from Subscriber:
  106.  *
  107.  * Input: 
  108.  *   SubscriberNumber
  109.  *
  110.  * Output:
  111.  *   Location
  112.  *   Changed by
  113.  *   Changed Timestamp
  114.  *   Name
  115.  */
  116. void
  117. start_T2(Ndb * pNDB, ThreadData * td){
  118.   DEBUG3("T2(%.*s, %p): - Startingn", SUBSCRIBER_NUMBER_LENGTH, 
  119.  td->transactionData.number, 
  120.  td->transactionData.location);
  121.   
  122.   int check;
  123.   NdbRecAttr * check2;
  124.   
  125.   NdbConnection * pCON = pNDB->startTransaction();
  126.   if (pCON == NULL)   
  127.     error_handler("T2-1: startTransaction", 
  128.   pNDB->getNdbErrorString(), 
  129.   pNDB->getNdbError());
  130.   
  131.   NdbOperation *MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE);
  132.   CHECK_NULL(MyOp, "T2: getNdbOperation", 
  133.      pCON);
  134.   
  135.   MyOp->readTuple();
  136.   MyOp->equal(IND_SUBSCRIBER_NUMBER,
  137.       td->transactionData.number);
  138.   MyOp->getValue(IND_SUBSCRIBER_LOCATION, 
  139.  (char *)&td->transactionData.location);
  140.   MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, 
  141.  td->transactionData.changed_by);
  142.   MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, 
  143.  td->transactionData.changed_time);
  144.   MyOp->getValue(IND_SUBSCRIBER_NAME, 
  145.  td->transactionData.name);
  146.   pCON->executeAsynchPrepare( Commit, T2_Callback, td ); 
  147. }
  148. void
  149. T2_Callback(int result, NdbConnection * pCON, void * threadData){
  150.   ThreadData * td = (ThreadData *)threadData;
  151.   DEBUG3("T2(%.*s, %p): - Completingn", SUBSCRIBER_NUMBER_LENGTH, 
  152.  td->transactionData.number, 
  153.  td->transactionData.location);
  154.   
  155.   CHECK_MINUS_ONE(result, "T2: Commit", pCON);
  156.   td->pNDB->closeTransaction(pCON);
  157.   complete_T2(td);
  158. }
  159. /**
  160.  * Transaction 3 - T3
  161.  *
  162.  * Read session details
  163.  *
  164.  * Input:
  165.  *   SubscriberNumber
  166.  *   ServerId
  167.  *   ServerBit
  168.  *
  169.  * Output:
  170.  *   BranchExecuted
  171.  *   SessionDetails
  172.  *   ChangedBy
  173.  *   ChangedTime
  174.  *   Location
  175.  */
  176. void
  177. start_T3(Ndb * pNDB, ThreadData * td){
  178.   DEBUG3("T3(%.*s, %.2d): - Startingn", SUBSCRIBER_NUMBER_LENGTH, 
  179.  td->transactionData.number, 
  180.  td->transactionData.server_id);
  181.   
  182.   int check;
  183.   NdbRecAttr * check2;
  184.   NdbConnection * pCON = startTransaction(pNDB, 
  185.      td->transactionData.server_id, 
  186.      td->transactionData.number);
  187.   if (pCON == NULL)   
  188.     error_handler("T3-1: startTranscation", 
  189.   pNDB->getNdbErrorString(), 
  190.   pNDB->getNdbError());
  191.   
  192.   NdbOperation *MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE);
  193.   CHECK_NULL(MyOp, "T3-1: getNdbOperation", 
  194.      pCON);
  195.   
  196.   MyOp->readTuple();
  197.   MyOp->equal(IND_SUBSCRIBER_NUMBER, 
  198.       td->transactionData.number);
  199.   MyOp->getValue(IND_SUBSCRIBER_LOCATION, 
  200.  (char *)&td->transactionData.location);
  201.   MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, 
  202.  td->transactionData.changed_by);
  203.   MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, 
  204.  td->transactionData.changed_time);
  205.   MyOp->getValue(IND_SUBSCRIBER_GROUP, 
  206.  (char *)&td->transactionData.group_id);
  207.   MyOp->getValue(IND_SUBSCRIBER_SESSIONS, 
  208.  (char *)&td->transactionData.sessions);
  209.   pCON->executeAsynchPrepare( NoCommit , T3_Callback_1, td); 
  210. }
  211. void
  212. T3_Callback_1(int result, NdbConnection * pCON, void * threadData){
  213.   ThreadData * td = (ThreadData *)threadData;
  214.   DEBUG3("T3(%.*s, %.2d): - Callback 1n", SUBSCRIBER_NUMBER_LENGTH, 
  215.  td->transactionData.number, 
  216.  td->transactionData.server_id);
  217.   CHECK_MINUS_ONE(result, "T3-1: NoCommit", pCON); 
  218.   NdbOperation * MyOp = pCON->getNdbOperation(GROUP_TABLE);
  219.   CHECK_NULL(MyOp, "T3-2: getNdbOperation", 
  220.      pCON);
  221.     
  222.   MyOp->readTuple();
  223.   MyOp->equal(IND_GROUP_ID,
  224.       (char*)&td->transactionData.group_id);
  225.   MyOp->getValue(IND_GROUP_ALLOW_READ, 
  226.  (char *)&td->transactionData.permission);
  227.   pCON->executeAsynchPrepare( NoCommit, T3_Callback_2, td ); 
  228. }
  229. void
  230. T3_Callback_2(int result, NdbConnection * pCON, void * threadData){
  231.   ThreadData * td = (ThreadData *)threadData;
  232.   
  233.   CHECK_MINUS_ONE(result, "T3-2: NoCommit", pCON); 
  234.   
  235.   Uint32 permission = td->transactionData.permission;
  236.   Uint32 sessions   = td->transactionData.sessions;
  237.   Uint32 server_bit = td->transactionData.server_bit;
  238.   if(((permission & server_bit) == server_bit) &&
  239.      ((sessions   & server_bit) == server_bit)){
  240.     
  241.     memcpy(td->transactionData.suffix,
  242.    &td->transactionData.number
  243.    [SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH],
  244.    SUBSCRIBER_NUMBER_SUFFIX_LENGTH);
  245.     DEBUG5("T3(%.*s, %.2d): - Callback 2 - reading(%.*s)n", 
  246.    SUBSCRIBER_NUMBER_LENGTH, 
  247.    td->transactionData.number, 
  248.    td->transactionData.server_id,
  249.    SUBSCRIBER_NUMBER_SUFFIX_LENGTH, 
  250.    td->transactionData.suffix);
  251.     
  252.     /* Operation 3 */
  253.     NdbOperation * MyOp = pCON->getNdbOperation(SESSION_TABLE);
  254.     CHECK_NULL(MyOp, "T3-3: getNdbOperation", 
  255.        pCON);
  256.     
  257.     MyOp->simpleRead();
  258.     MyOp->equal(IND_SESSION_SUBSCRIBER,
  259. (char*)td->transactionData.number);
  260.     MyOp->equal(IND_SESSION_SERVER,
  261. (char*)&td->transactionData.server_id);
  262.     MyOp->getValue(IND_SESSION_DATA, 
  263.    (char *)td->transactionData.session_details);
  264.     
  265.     /* Operation 4 */
  266.     MyOp = pCON->getNdbOperation(SERVER_TABLE);
  267.     CHECK_NULL(MyOp, "T3-4: getNdbOperation", 
  268.        pCON);
  269.     
  270.     MyOp->interpretedUpdateTuple();
  271.     MyOp->equal(IND_SERVER_ID,
  272. (char*)&td->transactionData.server_id);
  273.     MyOp->equal(IND_SERVER_SUBSCRIBER_SUFFIX,
  274. (char*)td->transactionData.suffix);
  275.     MyOp->incValue(IND_SERVER_READS, (uint32)1);
  276.     td->transactionData.branchExecuted = 1;
  277.   } else {
  278.     DEBUG3("T3(%.*s, %.2d): - Callback 2 - no readn",
  279.    SUBSCRIBER_NUMBER_LENGTH, 
  280.    td->transactionData.number, 
  281.    td->transactionData.server_id);
  282.     td->transactionData.branchExecuted = 0;
  283.   }
  284.   pCON->executeAsynchPrepare( Commit, T3_Callback_3, td ); 
  285. }
  286. void
  287. T3_Callback_3(int result, NdbConnection * pCON, void * threadData){
  288.   ThreadData * td = (ThreadData *)threadData;  
  289.   DEBUG3("T3(%.*s, %.2d): - Completingn", SUBSCRIBER_NUMBER_LENGTH, 
  290.  td->transactionData.number, 
  291.  td->transactionData.server_id);
  292.   
  293.   CHECK_MINUS_ONE(result, "T3-3: Commit", pCON); 
  294.   
  295.   td->pNDB->closeTransaction(pCON);
  296.   complete_T3(td);
  297. }
  298. /**
  299.  * Transaction 4 - T4
  300.  * 
  301.  * Create session
  302.  *
  303.  * Input:
  304.  *   SubscriberNumber
  305.  *   ServerId
  306.  *   ServerBit
  307.  *   SessionDetails,
  308.  *   DoRollback
  309.  * Output:
  310.  *   ChangedBy
  311.  *   ChangedTime
  312.  *   Location
  313.  *   BranchExecuted
  314.  */
  315. void
  316. start_T4(Ndb * pNDB, ThreadData * td){
  317.   DEBUG3("T4(%.*s, %.2d): - Startingn", SUBSCRIBER_NUMBER_LENGTH, 
  318.  td->transactionData.number, 
  319.  td->transactionData.server_id);
  320.   
  321.   int check;
  322.   NdbRecAttr * check2;
  323.   
  324.   NdbConnection * pCON = startTransaction(pNDB, 
  325.   td->transactionData.server_id, 
  326.   td->transactionData.number);
  327.   if (pCON == NULL)   
  328.     error_handler("T4-1: startTranscation", 
  329.   pNDB->getNdbErrorString(), 
  330.   pNDB->getNdbError());
  331.   
  332.   NdbOperation *MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE);
  333.   CHECK_NULL(MyOp, "T4-1: getNdbOperation", 
  334.      pCON);
  335.   
  336.   MyOp->interpretedUpdateTuple();
  337.   MyOp->equal(IND_SUBSCRIBER_NUMBER, 
  338.       td->transactionData.number);
  339.   MyOp->getValue(IND_SUBSCRIBER_LOCATION, 
  340.  (char *)&td->transactionData.location);
  341.   MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, 
  342.  td->transactionData.changed_by);
  343.   MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, 
  344.  td->transactionData.changed_time);
  345.   MyOp->getValue(IND_SUBSCRIBER_GROUP,
  346.  (char *)&td->transactionData.group_id);
  347.   MyOp->getValue(IND_SUBSCRIBER_SESSIONS,
  348.  (char *)&td->transactionData.sessions); 
  349.   MyOp->incValue(IND_SUBSCRIBER_SESSIONS, 
  350.  (uint32)td->transactionData.server_bit);
  351.   pCON->executeAsynchPrepare( NoCommit , T4_Callback_1, td); 
  352. }
  353. void
  354. T4_Callback_1(int result, NdbConnection * pCON, void * threadData){
  355.   CHECK_MINUS_ONE(result, "T4-1: NoCommit", pCON); 
  356.   ThreadData * td = (ThreadData *)threadData;  
  357.   
  358.   DEBUG3("T4(%.*s, %.2d): - Callback 1n", 
  359.  SUBSCRIBER_NUMBER_LENGTH, 
  360.  td->transactionData.number, 
  361.  td->transactionData.server_id);
  362.   NdbOperation * MyOp = pCON->getNdbOperation(GROUP_TABLE);
  363.   CHECK_NULL(MyOp, "T4-2: getNdbOperation", 
  364.      pCON);
  365.   
  366.   MyOp->readTuple();
  367.   MyOp->equal(IND_GROUP_ID,
  368.       (char*)&td->transactionData.group_id);
  369.   MyOp->getValue(IND_GROUP_ALLOW_INSERT, 
  370.  (char *)&td->transactionData.permission);
  371.   pCON->executeAsynchPrepare( NoCommit , T4_Callback_2, td); 
  372. }
  373. void
  374. T4_Callback_2(int result, NdbConnection * pCON, void * threadData){
  375.   CHECK_MINUS_ONE(result, "T4-2: NoCommit", pCON); 
  376.   ThreadData * td = (ThreadData *)threadData;  
  377.   Uint32 permission = td->transactionData.permission;
  378.   Uint32 sessions   = td->transactionData.sessions;
  379.   Uint32 server_bit = td->transactionData.server_bit;
  380.   
  381.   if(((permission & server_bit) == server_bit) &&
  382.      ((sessions   & server_bit) == 0)){
  383.     
  384.     memcpy(td->transactionData.suffix,
  385.    &td->transactionData.number
  386.    [SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH], 
  387.    SUBSCRIBER_NUMBER_SUFFIX_LENGTH);
  388.     
  389.     DEBUG5("T4(%.*s, %.2d): - Callback 2 - inserting(%.*s)n", 
  390.    SUBSCRIBER_NUMBER_LENGTH, 
  391.    td->transactionData.number, 
  392.    td->transactionData.server_id,
  393.    SUBSCRIBER_NUMBER_SUFFIX_LENGTH, 
  394.    td->transactionData.suffix);
  395.     
  396.     /* Operation 3 */
  397.     
  398.     NdbOperation * MyOp = pCON->getNdbOperation(SESSION_TABLE);
  399.     CHECK_NULL(MyOp, "T4-3: getNdbOperation", 
  400.        pCON);
  401.     
  402.     MyOp->insertTuple();
  403.     MyOp->equal(IND_SESSION_SUBSCRIBER,
  404. (char*)td->transactionData.number);
  405.     MyOp->equal(IND_SESSION_SERVER,
  406. (char*)&td->transactionData.server_id);
  407.     MyOp->setValue(SESSION_DATA, 
  408.    (char *)td->transactionData.session_details);
  409.     /* Operation 4 */
  410.     
  411.     /* Operation 5 */
  412.     MyOp = pCON->getNdbOperation(SERVER_TABLE);
  413.     CHECK_NULL(MyOp, "T4-5: getNdbOperation", 
  414.        pCON);
  415.     
  416.     MyOp->interpretedUpdateTuple();
  417.     MyOp->equal(IND_SERVER_ID,
  418. (char*)&td->transactionData.server_id);
  419.     MyOp->equal(IND_SERVER_SUBSCRIBER_SUFFIX,
  420. (char*)td->transactionData.suffix);
  421.     MyOp->incValue(IND_SERVER_INSERTS, (uint32)1);
  422.     td->transactionData.branchExecuted = 1;
  423.   } else {
  424.     td->transactionData.branchExecuted = 0;
  425.     DEBUG5("T4(%.*s, %.2d): - Callback 2 - %s %sn",
  426.    SUBSCRIBER_NUMBER_LENGTH, 
  427.    td->transactionData.number, 
  428.    td->transactionData.server_id,
  429.    ((permission & server_bit) ? 
  430.     "permission - " : "no permission - "),
  431.    ((sessions   & server_bit) ? 
  432.     "in session - " : "no in session - "));
  433.   }
  434.   
  435.   if(!td->transactionData.do_rollback && td->transactionData.branchExecuted){
  436.     pCON->executeAsynchPrepare(Commit, T4_Callback_3, td); 
  437.   } else {
  438.     pCON->executeAsynchPrepare(Rollback, T4_Callback_3, td);
  439.   }
  440. }
  441. void
  442. T4_Callback_3(int result, NdbConnection * pCON, void * threadData){
  443.   CHECK_MINUS_ONE(result, "T4-3: Commit", pCON); 
  444.   ThreadData * td = (ThreadData *)threadData;  
  445.   
  446.   DEBUG3("T4(%.*s, %.2d): - Completingn", 
  447.  SUBSCRIBER_NUMBER_LENGTH, 
  448.  td->transactionData.number, 
  449.  td->transactionData.server_id);
  450.   td->pNDB->closeTransaction(pCON);
  451.   complete_T4(td);
  452. }
  453. /**
  454.  * Transaction 5 - T5
  455.  * 
  456.  * Delete session
  457.  *
  458.  * Input:
  459.  *   SubscriberNumber
  460.  *   ServerId
  461.  *   ServerBit
  462.  *   DoRollback
  463.  * Output:
  464.  *   ChangedBy
  465.  *   ChangedTime
  466.  *   Location
  467.  *   BranchExecuted
  468.  */
  469. void
  470. start_T5(Ndb * pNDB, ThreadData * td){
  471.   DEBUG3("T5(%.*s, %.2d): - Startingn", SUBSCRIBER_NUMBER_LENGTH, 
  472.  td->transactionData.number, 
  473.  td->transactionData.server_id);
  474.   int check;
  475.   NdbRecAttr * check2;
  476.   
  477.   NdbConnection * pCON = pNDB->startTransaction();
  478.   if (pCON == NULL)   
  479.     error_handler("T5-1: startTranscation", 
  480.   pNDB->getNdbErrorString(), 
  481.   pNDB->getNdbError());
  482.   
  483.   NdbOperation * MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE);
  484.   CHECK_NULL(MyOp, "T5-1: getNdbOperation", 
  485.      pCON);
  486.   
  487.   MyOp->interpretedUpdateTuple();
  488.   MyOp->equal(IND_SUBSCRIBER_NUMBER, 
  489.       td->transactionData.number);
  490.   MyOp->getValue(IND_SUBSCRIBER_LOCATION, 
  491.  (char *)&td->transactionData.location);
  492.   MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, 
  493.  td->transactionData.changed_by);
  494.   MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, 
  495.  td->transactionData.changed_time);
  496.   MyOp->getValue(IND_SUBSCRIBER_GROUP,
  497.  (char *)&td->transactionData.group_id);
  498.   MyOp->getValue(IND_SUBSCRIBER_SESSIONS,
  499.  (char *)&td->transactionData.sessions);
  500.   MyOp->subValue(IND_SUBSCRIBER_SESSIONS, 
  501.  (uint32)td->transactionData.server_bit);
  502.   pCON->executeAsynchPrepare( NoCommit, T5_Callback_1, td ); 
  503. }
  504. void
  505. T5_Callback_1(int result, NdbConnection * pCON, void * threadData){
  506.   CHECK_MINUS_ONE(result, "T5-1: NoCommit", pCON); 
  507.   ThreadData * td = (ThreadData *)threadData;  
  508.   DEBUG3("T5(%.*s, %.2d): - Callback 1n", 
  509.  SUBSCRIBER_NUMBER_LENGTH, 
  510.  td->transactionData.number, 
  511.  td->transactionData.server_id);
  512.   
  513.   NdbOperation * MyOp = pCON->getNdbOperation(GROUP_TABLE);
  514.   CHECK_NULL(MyOp, "T5-2: getNdbOperation", 
  515.      pCON);
  516.   
  517.   MyOp->readTuple();
  518.   MyOp->equal(IND_GROUP_ID,
  519.       (char*)&td->transactionData.group_id);
  520.   MyOp->getValue(IND_GROUP_ALLOW_DELETE, 
  521.  (char *)&td->transactionData.permission);
  522.   pCON->executeAsynchPrepare( NoCommit, T5_Callback_2, td ); 
  523. }
  524. void
  525. T5_Callback_2(int result, NdbConnection * pCON, void * threadData){
  526.   CHECK_MINUS_ONE(result, "T5-2: NoCommit", pCON); 
  527.   ThreadData * td = (ThreadData *)threadData;  
  528.   Uint32 permission = td->transactionData.permission;
  529.   Uint32 sessions   = td->transactionData.sessions;
  530.   Uint32 server_bit = td->transactionData.server_bit;
  531.   if(((permission & server_bit) == server_bit) &&
  532.      ((sessions   & server_bit) == server_bit)){
  533.     
  534.     memcpy(td->transactionData.suffix,
  535.    &td->transactionData.number
  536.    [SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH], 
  537.    SUBSCRIBER_NUMBER_SUFFIX_LENGTH);
  538.   
  539.     DEBUG5("T5(%.*s, %.2d): - Callback 2 - deleting(%.*s)n", 
  540.    SUBSCRIBER_NUMBER_LENGTH, 
  541.    td->transactionData.number, 
  542.    td->transactionData.server_id,
  543.    SUBSCRIBER_NUMBER_SUFFIX_LENGTH, 
  544.    td->transactionData.suffix);
  545.     
  546.     /* Operation 3 */
  547.     NdbOperation * MyOp = pCON->getNdbOperation(SESSION_TABLE);
  548.     CHECK_NULL(MyOp, "T5-3: getNdbOperation", 
  549.        pCON);
  550.     
  551.     MyOp->deleteTuple();
  552.     MyOp->equal(IND_SESSION_SUBSCRIBER,
  553. (char*)td->transactionData.number);
  554.     MyOp->equal(IND_SESSION_SERVER,
  555. (char*)&td->transactionData.server_id);
  556.     /* Operation 4 */
  557.     
  558.     /* Operation 5 */
  559.     MyOp = pCON->getNdbOperation(SERVER_TABLE);
  560.     CHECK_NULL(MyOp, "T5-5: getNdbOperation", 
  561.        pCON);
  562.     
  563.     MyOp->interpretedUpdateTuple();
  564.     MyOp->equal(IND_SERVER_ID,
  565. (char*)&td->transactionData.server_id);
  566.     MyOp->equal(IND_SERVER_SUBSCRIBER_SUFFIX,
  567. (char*)td->transactionData.suffix);
  568.     MyOp->incValue(IND_SERVER_DELETES, (uint32)1);
  569.     td->transactionData.branchExecuted = 1;
  570.   } else {
  571.     td->transactionData.branchExecuted = 0;
  572.     DEBUG5("T5(%.*s, %.2d): - Callback 2 - no delete - %s %sn", 
  573.    SUBSCRIBER_NUMBER_LENGTH, 
  574.    td->transactionData.number, 
  575.    td->transactionData.server_id,
  576.    ((permission & server_bit) ? 
  577.     "permission - " : "no permission - "),
  578.    ((sessions   & server_bit) ? 
  579.     "in session - " : "no in session - "));
  580.   }
  581.   
  582.   if(!td->transactionData.do_rollback && td->transactionData.branchExecuted){
  583.     pCON->executeAsynchPrepare(Commit, T5_Callback_3, td); 
  584.   } else {
  585.     pCON->executeAsynchPrepare(Rollback, T5_Callback_3, td);
  586.   }
  587. }
  588. void
  589. T5_Callback_3(int result, NdbConnection * pCON, void * threadData){
  590.   CHECK_MINUS_ONE(result, "T5-3: Commit", pCON); 
  591.   ThreadData * td = (ThreadData *)threadData;  
  592.   DEBUG3("T5(%.*s, %.2d): - Completingn", 
  593.  SUBSCRIBER_NUMBER_LENGTH, 
  594.  td->transactionData.number, 
  595.  td->transactionData.server_id);
  596.   
  597.   td->pNDB->closeTransaction(pCON);
  598.   complete_T5(td);
  599. }