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

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 <string.h>
  15. #include "userHandle.h"
  16. #include "userInterface.h"
  17. #include "macros.h"
  18. #include "ndb_schema.hpp"
  19. #include "ndb_error.hpp"
  20. #include <NdbApi.hpp>
  21. void
  22. userCheckpoint(UserHandle *uh){
  23. }
  24. inline
  25. NdbConnection *
  26. startTransaction(Ndb * pNDB, ServerId inServerId, const SubscriberNumber inNumber){
  27.   
  28.   const int keyDataLenBytes    = sizeof(ServerId)+SUBSCRIBER_NUMBER_LENGTH;
  29.   const int keyDataLen_64Words = keyDataLenBytes >> 3;
  30.   Uint64 keyDataBuf[keyDataLen_64Words+1]; // The "+1" is for rounding...
  31.   
  32.   char     * keyDataBuf_charP = (char *)&keyDataBuf[0];
  33.   Uint32  * keyDataBuf_wo32P = (Uint32 *)&keyDataBuf[0];
  34.   
  35.   // Server Id comes first
  36.   keyDataBuf_wo32P[0] = inServerId;
  37.   // Then subscriber number
  38.   memcpy(&keyDataBuf_charP[sizeof(ServerId)], inNumber, SUBSCRIBER_NUMBER_LENGTH);
  39.   return pNDB->startTransaction(0, keyDataBuf_charP, keyDataLenBytes);
  40. }
  41. /**
  42.  * Transaction 1 - T1 
  43.  *
  44.  * Update location and changed by/time on a subscriber
  45.  *
  46.  * Input: 
  47.  *   SubscriberNumber,
  48.  *   Location,
  49.  *   ChangedBy,
  50.  *   ChangedTime
  51.  *
  52.  * Output:
  53.  */
  54. void
  55. userTransaction_T1(UserHandle * uh,
  56.    SubscriberNumber number, 
  57.    Location new_location, 
  58.    ChangedBy changed_by, 
  59.    ChangedTime changed_time){
  60.   Ndb * pNDB = uh->pNDB;
  61.   DEBUG2("T1(%.*s):n", SUBSCRIBER_NUMBER_LENGTH, number);
  62.   int check;
  63.   NdbRecAttr * check2;
  64.   NdbConnection * MyTransaction = pNDB->startTransaction();
  65.   if (MyTransaction != NULL) {
  66.     NdbOperation *MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE);
  67.     if (MyOperation != NULL) {  
  68.       MyOperation->updateTuple();  
  69.       MyOperation->equal(IND_SUBSCRIBER_NUMBER,
  70.                          number);
  71.       MyOperation->setValue(IND_SUBSCRIBER_LOCATION, 
  72.             (char *)&new_location);
  73.       MyOperation->setValue(IND_SUBSCRIBER_CHANGED_BY, 
  74.     changed_by);
  75.       MyOperation->setValue(IND_SUBSCRIBER_CHANGED_TIME, 
  76.     changed_time);
  77.       check = MyTransaction->execute( Commit );
  78.       if (check != -1) {
  79.         pNDB->closeTransaction(MyTransaction);
  80.         return;
  81.       } else {
  82.         CHECK_MINUS_ONE(check, "T1: Commit", 
  83.         MyTransaction);
  84.       }//if
  85.     } else {
  86.       CHECK_NULL(MyOperation, "T1: getNdbOperation", MyTransaction);
  87.     }//if
  88.   } else {
  89.     error_handler("T1-1: startTranscation", pNDB->getNdbErrorString(), pNDB->getNdbError());
  90.   }//if
  91. }
  92. /**
  93.  * Transaction 2 - T2
  94.  *
  95.  * Read from Subscriber:
  96.  *
  97.  * Input: 
  98.  *   SubscriberNumber
  99.  *
  100.  * Output:
  101.  *   Location
  102.  *   Changed by
  103.  *   Changed Timestamp
  104.  *   Name
  105.  */
  106. void
  107. userTransaction_T2(UserHandle * uh,
  108.    SubscriberNumber number, 
  109.    Location * readLocation, 
  110.    ChangedBy changed_by, 
  111.    ChangedTime changed_time,
  112.    SubscriberName subscriberName){
  113.   Ndb * pNDB = uh->pNDB;
  114.   DEBUG2("T2(%.*s):n", SUBSCRIBER_NUMBER_LENGTH, number);
  115.   int check;
  116.   NdbRecAttr * check2;
  117.   NdbConnection * MyTransaction = pNDB->startTransaction();
  118.   if (MyTransaction == NULL)   
  119.     error_handler("T2-1: startTransaction", pNDB->getNdbErrorString(), pNDB->getNdbError());
  120.   NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE);
  121.   CHECK_NULL(MyOperation, "T2: getNdbOperation", 
  122.      MyTransaction);
  123.   
  124.   MyOperation->readTuple();
  125.   MyOperation->equal(IND_SUBSCRIBER_NUMBER, 
  126.      number);
  127.   MyOperation->getValue(IND_SUBSCRIBER_LOCATION, 
  128. (char *)readLocation);
  129.   MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, 
  130. changed_by);
  131.   MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, 
  132.                         changed_time);
  133.   MyOperation->getValue(IND_SUBSCRIBER_NAME, 
  134. subscriberName);
  135.   check = MyTransaction->execute( Commit ); 
  136.   CHECK_MINUS_ONE(check, "T2: Commit", 
  137.   MyTransaction);  
  138.   pNDB->closeTransaction(MyTransaction);
  139. }
  140. /**
  141.  * Transaction 3 - T3
  142.  *
  143.  * Read session details
  144.  *
  145.  * Input:
  146.  *   SubscriberNumber
  147.  *   ServerId
  148.  *   ServerBit
  149.  *
  150.  * Output:
  151.  *   BranchExecuted
  152.  *   SessionDetails
  153.  *   ChangedBy
  154.  *   ChangedTime
  155.  *   Location
  156.  */
  157. void
  158. userTransaction_T3(UserHandle * uh,
  159.    SubscriberNumber   inNumber,
  160.    ServerId           inServerId,
  161.    ServerBit          inServerBit,
  162.    SessionDetails     outSessionDetails,
  163.    BranchExecuted   * outBranchExecuted){
  164.   Ndb * pNDB = uh->pNDB;
  165.   char               outChangedBy   [sizeof(ChangedBy)  +(4-(sizeof(ChangedBy)   & 3))];
  166.   char               outChangedTime [sizeof(ChangedTime)+(4-(sizeof(ChangedTime) & 3))];
  167.   Location           outLocation;
  168.   GroupId            groupId;
  169.   ActiveSessions     sessions;
  170.   Permission         permission;
  171.   SubscriberSuffix   inSuffix;
  172.   DEBUG3("T3(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId);
  173.   int check;
  174.   NdbRecAttr * check2;
  175.   NdbConnection * MyTransaction = startTransaction(pNDB, inServerId, inNumber);
  176.   if (MyTransaction == NULL)   
  177.     error_handler("T3-1: startTranscation", pNDB->getNdbErrorString(), pNDB->getNdbError());
  178.   NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE);
  179.   CHECK_NULL(MyOperation, "T3-1: getNdbOperation", 
  180.      MyTransaction);
  181.     
  182.   MyOperation->readTuple();
  183.   MyOperation->equal(IND_SUBSCRIBER_NUMBER, 
  184.      inNumber);
  185.   MyOperation->getValue(IND_SUBSCRIBER_LOCATION, 
  186. (char *)&outLocation);
  187.   MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, 
  188. outChangedBy);
  189.   MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, 
  190.                         outChangedTime);
  191.   MyOperation->getValue(IND_SUBSCRIBER_GROUP,
  192. (char *)&groupId);
  193.   MyOperation->getValue(IND_SUBSCRIBER_SESSIONS,
  194. (char *)&sessions);
  195.   check = MyTransaction->execute( NoCommit ); 
  196.   CHECK_MINUS_ONE(check, "T3-1: NoCommit", 
  197.   MyTransaction);
  198.   
  199.     /* Operation 2 */
  200.   MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE);
  201.   CHECK_NULL(MyOperation, "T3-2: getNdbOperation", 
  202.      MyTransaction);
  203.   
  204.   
  205.   MyOperation->readTuple();
  206.   MyOperation->equal(IND_GROUP_ID,
  207.      (char*)&groupId);
  208.   MyOperation->getValue(IND_GROUP_ALLOW_READ, 
  209. (char *)&permission);
  210.   check = MyTransaction->execute( NoCommit ); 
  211.   CHECK_MINUS_ONE(check, "T3-2: NoCommit", 
  212.   MyTransaction);
  213.   
  214.   if(((permission & inServerBit) == inServerBit) &&
  215.      ((sessions   & inServerBit) == inServerBit)){
  216.     memcpy(inSuffix,
  217.    &inNumber[SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH], SUBSCRIBER_NUMBER_SUFFIX_LENGTH);
  218.     DEBUG2("reading(%.*s) - ", SUBSCRIBER_NUMBER_SUFFIX_LENGTH, inSuffix);
  219.     
  220.     /* Operation 3 */
  221.     MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE);
  222.     CHECK_NULL(MyOperation, "T3-3: getNdbOperation", 
  223.        MyTransaction);
  224.     
  225.     MyOperation->simpleRead();
  226.   
  227.     MyOperation->equal(IND_SESSION_SUBSCRIBER,
  228.        (char*)inNumber);
  229.     MyOperation->equal(IND_SESSION_SERVER,
  230.        (char*)&inServerId);
  231.     MyOperation->getValue(IND_SESSION_DATA, 
  232.   (char *)outSessionDetails);
  233.     /* Operation 4 */
  234.     MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE);
  235.     CHECK_NULL(MyOperation, "T3-4: getNdbOperation", 
  236.        MyTransaction);
  237.     
  238.     MyOperation->interpretedUpdateTuple();
  239.     MyOperation->equal(IND_SERVER_ID,
  240.        (char*)&inServerId);
  241.     MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX,
  242.         (char*)inSuffix);
  243.     MyOperation->incValue(IND_SERVER_READS, (uint32)1);
  244.     (* outBranchExecuted) = 1;
  245.   } else {
  246.     (* outBranchExecuted) = 0;
  247.   }
  248.   DEBUG("commit...");
  249.   check = MyTransaction->execute( Commit ); 
  250.   CHECK_MINUS_ONE(check, "T3: Commit", 
  251.   MyTransaction);
  252.   
  253.   pNDB->closeTransaction(MyTransaction);
  254.   
  255.   DEBUG("donen");
  256. }
  257. /**
  258.  * Transaction 4 - T4
  259.  * 
  260.  * Create session
  261.  *
  262.  * Input:
  263.  *   SubscriberNumber
  264.  *   ServerId
  265.  *   ServerBit
  266.  *   SessionDetails,
  267.  *   DoRollback
  268.  * Output:
  269.  *   ChangedBy
  270.  *   ChangedTime
  271.  *   Location
  272.  *   BranchExecuted
  273.  */
  274. void
  275. userTransaction_T4(UserHandle * uh,
  276.    SubscriberNumber   inNumber,
  277.    ServerId           inServerId,
  278.    ServerBit          inServerBit,
  279.    SessionDetails     inSessionDetails,
  280.    DoRollback         inDoRollback,
  281.    BranchExecuted   * outBranchExecuted){
  282.   
  283.   Ndb * pNDB = uh->pNDB;
  284.   
  285.   char               outChangedBy   [sizeof(ChangedBy)  +(4-(sizeof(ChangedBy)   & 3))];
  286.   char               outChangedTime [sizeof(ChangedTime)+(4-(sizeof(ChangedTime) & 3))];
  287.   Location         outLocation;
  288.   GroupId          groupId;
  289.   ActiveSessions   sessions;
  290.   Permission       permission;
  291.   SubscriberSuffix inSuffix;
  292.   DEBUG3("T4(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId);
  293.   int check;
  294.   NdbRecAttr * check2;
  295.   NdbConnection * MyTransaction = startTransaction(pNDB, inServerId, inNumber);
  296.   if (MyTransaction == NULL)   
  297.     error_handler("T4-1: startTranscation", pNDB->getNdbErrorString(), pNDB->getNdbError());
  298.   NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE);
  299.   CHECK_NULL(MyOperation, "T4-1: getNdbOperation", 
  300.      MyTransaction);
  301.   
  302.   MyOperation->interpretedUpdateTuple();
  303.   MyOperation->equal(IND_SUBSCRIBER_NUMBER, 
  304.      inNumber);
  305.   MyOperation->getValue(IND_SUBSCRIBER_LOCATION, 
  306. (char *)&outLocation);
  307.   MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, 
  308.         outChangedBy);
  309.   MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, 
  310.                         outChangedTime);
  311.   MyOperation->getValue(IND_SUBSCRIBER_GROUP,
  312. (char *)&groupId);
  313.   MyOperation->getValue(IND_SUBSCRIBER_SESSIONS,
  314. (char *)&sessions); 
  315.   MyOperation->incValue(IND_SUBSCRIBER_SESSIONS, 
  316. (uint32)inServerBit);
  317.   check = MyTransaction->execute( NoCommit ); 
  318.     /* Operation 2 */
  319.   MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE);
  320.   CHECK_NULL(MyOperation, "T4-2: getNdbOperation", 
  321.      MyTransaction);
  322.   
  323.   MyOperation->readTuple();
  324.   MyOperation->equal(IND_GROUP_ID,
  325.      (char*)&groupId);
  326.   MyOperation->getValue(IND_GROUP_ALLOW_INSERT, 
  327. (char *)&permission);
  328.   check = MyTransaction->execute( NoCommit ); 
  329.   CHECK_MINUS_ONE(check, "T4-2: NoCommit", 
  330.   MyTransaction);
  331.   
  332.   if(((permission & inServerBit) == inServerBit) &&
  333.      ((sessions   & inServerBit) == 0)){
  334.   
  335.     memcpy(inSuffix,
  336.    &inNumber[SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH], SUBSCRIBER_NUMBER_SUFFIX_LENGTH);
  337.     DEBUG2("inserting(%.*s) - ", SUBSCRIBER_NUMBER_SUFFIX_LENGTH, inSuffix);
  338.   
  339.     /* Operation 3 */
  340.     
  341.     MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE);
  342.     CHECK_NULL(MyOperation, "T4-3: getNdbOperation", 
  343.        MyTransaction);
  344.     
  345.     MyOperation->insertTuple();
  346.     MyOperation->equal(IND_SESSION_SUBSCRIBER,
  347.       (char*)inNumber);
  348.     MyOperation->equal(IND_SESSION_SERVER,
  349.        (char*)&inServerId);
  350.     MyOperation->setValue(SESSION_DATA, 
  351.   (char *)inSessionDetails);
  352.     /* Operation 4 */
  353.     /* Operation 5 */
  354.     MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE);
  355.     CHECK_NULL(MyOperation, "T4-5: getNdbOperation", 
  356.        MyTransaction);
  357.     
  358.     MyOperation->interpretedUpdateTuple();
  359.     MyOperation->equal(IND_SERVER_ID,
  360.        (char*)&inServerId);
  361.     MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX,
  362.        (char*)inSuffix);
  363.     MyOperation->incValue(IND_SERVER_INSERTS, (uint32)1);
  364.     (* outBranchExecuted) = 1;
  365.   } else {
  366.     (* outBranchExecuted) = 0;
  367.     DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - "));
  368.     DEBUG1("%s", ((sessions   & inServerBit) ? "in session - " : "no in session - "));
  369.   }
  370.   if(!inDoRollback && (* outBranchExecuted)){
  371.     DEBUG("commitn");
  372.     check = MyTransaction->execute( Commit ); 
  373.     CHECK_MINUS_ONE(check, "T4: Commit", 
  374.     MyTransaction);
  375.   } else {
  376.     DEBUG("rollbackn");
  377.     check = MyTransaction->execute(Rollback);
  378.     CHECK_MINUS_ONE(check, "T4:Rollback", 
  379.     MyTransaction);
  380.     
  381.   }
  382.   
  383.   pNDB->closeTransaction(MyTransaction);
  384. }
  385. /**
  386.  * Transaction 5 - T5
  387.  * 
  388.  * Delete session
  389.  *
  390.  * Input:
  391.  *   SubscriberNumber
  392.  *   ServerId
  393.  *   ServerBit
  394.  *   DoRollback
  395.  * Output:
  396.  *   ChangedBy
  397.  *   ChangedTime
  398.  *   Location
  399.  *   BranchExecuted
  400.  */
  401. void
  402. userTransaction_T5(UserHandle * uh,
  403.    SubscriberNumber   inNumber,
  404.    ServerId           inServerId,
  405.    ServerBit          inServerBit,
  406.    DoRollback         inDoRollback,
  407.    BranchExecuted   * outBranchExecuted){
  408.   Ndb * pNDB = uh->pNDB;
  409.   DEBUG3("T5(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId);
  410.   NdbConnection * MyTransaction = 0;
  411.   NdbOperation  * MyOperation = 0;
  412.   char             outChangedBy   [sizeof(ChangedBy)  +(4-(sizeof(ChangedBy)   & 3))];
  413.   char             outChangedTime [sizeof(ChangedTime)+(4-(sizeof(ChangedTime) & 3))];
  414.   Location         outLocation;
  415.   GroupId          groupId;
  416.   ActiveSessions   sessions;
  417.   Permission       permission;
  418.   SubscriberSuffix inSuffix;
  419.   int check;
  420.   NdbRecAttr * check2;
  421.   MyTransaction = pNDB->startTransaction();
  422.   if (MyTransaction == NULL)   
  423.     error_handler("T5-1: startTranscation", pNDB->getNdbErrorString(), pNDB->getNdbError());
  424.   
  425.   MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE);
  426.   CHECK_NULL(MyOperation, "T5-1: getNdbOperation", 
  427.      MyTransaction);
  428.   
  429.   MyOperation->interpretedUpdateTuple();
  430.   MyOperation->equal(IND_SUBSCRIBER_NUMBER, 
  431.      inNumber);
  432.   MyOperation->getValue(IND_SUBSCRIBER_LOCATION, 
  433.         (char *)&outLocation);
  434.   MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, 
  435. &outChangedBy[0]);
  436.   MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, 
  437.                         &outChangedTime[0]);
  438.   MyOperation->getValue(IND_SUBSCRIBER_GROUP,
  439.         (char *)&groupId);
  440.   MyOperation->getValue(IND_SUBSCRIBER_SESSIONS,
  441.         (char *)&sessions);
  442.   MyOperation->subValue(IND_SUBSCRIBER_SESSIONS, 
  443.         (uint32)inServerBit);
  444.   MyTransaction->execute( NoCommit ); 
  445.     /* Operation 2 */
  446.   MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE);
  447.   CHECK_NULL(MyOperation, "T5-2: getNdbOperation", 
  448.      MyTransaction);
  449.     
  450.   MyOperation->readTuple();
  451.   MyOperation->equal(IND_GROUP_ID,
  452.      (char*)&groupId);
  453.   MyOperation->getValue(IND_GROUP_ALLOW_DELETE, 
  454. (char *)&permission);
  455.   check = MyTransaction->execute( NoCommit ); 
  456.   CHECK_MINUS_ONE(check, "T5-2: NoCommit", 
  457.   MyTransaction);
  458.   
  459.   if(((permission & inServerBit) == inServerBit) &&
  460.      ((sessions   & inServerBit) == inServerBit)){
  461.   
  462.     memcpy(inSuffix,
  463.    &inNumber[SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH], SUBSCRIBER_NUMBER_SUFFIX_LENGTH);
  464.     
  465.     DEBUG2("deleting(%.*s) - ", SUBSCRIBER_NUMBER_SUFFIX_LENGTH, inSuffix);
  466.     /* Operation 3 */
  467.     MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE);
  468.     CHECK_NULL(MyOperation, "T5-3: getNdbOperation", 
  469.        MyTransaction);
  470.     
  471.     MyOperation->deleteTuple();
  472.     MyOperation->equal(IND_SESSION_SUBSCRIBER,
  473.        (char*)inNumber);
  474.     MyOperation->equal(IND_SESSION_SERVER,
  475.        (char*)&inServerId);
  476.     /* Operation 4 */
  477.         
  478.     /* Operation 5 */
  479.     MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE);
  480.     CHECK_NULL(MyOperation, "T5-5: getNdbOperation", 
  481.        MyTransaction);
  482.     
  483.     
  484.     MyOperation->interpretedUpdateTuple();
  485.     MyOperation->equal(IND_SERVER_ID,
  486.        (char*)&inServerId);
  487.     MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX,
  488.        (char*)inSuffix);
  489.     MyOperation->incValue(IND_SERVER_DELETES, (uint32)1);
  490.     (* outBranchExecuted) = 1;
  491.   } else {
  492.     (* outBranchExecuted) = 0;
  493.     DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - "));
  494.     DEBUG1("%s", ((sessions   & inServerBit) ? "in session - " : "no in session - "));
  495.   }
  496.   if(!inDoRollback && (* outBranchExecuted)){
  497.     DEBUG("commitn");
  498.     check = MyTransaction->execute( Commit ); 
  499.     CHECK_MINUS_ONE(check, "T5: Commit", 
  500.     MyTransaction);
  501.   } else {
  502.     DEBUG("rollbackn");
  503.     check = MyTransaction->execute(Rollback);
  504.     CHECK_MINUS_ONE(check, "T5:Rollback", 
  505.     MyTransaction);
  506.     
  507.   }
  508.   
  509.   pNDB->closeTransaction(MyTransaction);
  510. }