MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ndb_async1.cpp
1 /*
2  Copyright (C) 2003-2006 MySQL AB
3  All rights reserved. Use is subject to license terms.
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; version 2 of the License.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 
19 //#define DEBUG_ON
20 
21 #include "userInterface.h"
22 
23 #include "macros.h"
24 #include "ndb_schema.hpp"
25 #include "ndb_error.hpp"
26 
27 #include <NdbApi.hpp>
28 
29 inline
31 startTransaction(Ndb * pNDB,
32  ServerId inServerId,
33  const SubscriberNumber inNumber){
34 
35  const int keyDataLenBytes = sizeof(ServerId)+SUBSCRIBER_NUMBER_LENGTH;
36  const int keyDataLen_64Words = keyDataLenBytes >> 3;
37 
38  Uint64 keyDataBuf[keyDataLen_64Words+1]; // The "+1" is for rounding...
39 
40  char * keyDataBuf_charP = (char *)&keyDataBuf[0];
41  Uint32 * keyDataBuf_wo32P = (Uint32 *)&keyDataBuf[0];
42 
43  // Server Id comes first
44  keyDataBuf_wo32P[0] = inServerId;
45  // Then subscriber number
46  memcpy(&keyDataBuf_charP[sizeof(ServerId)], inNumber,
47  SUBSCRIBER_NUMBER_LENGTH);
48 
49  return pNDB->startTransaction(0, keyDataBuf_charP, keyDataLenBytes);
50 }
51 
52 void T1_Callback(int result, NdbConnection * pCon, void * threadData);
53 void T2_Callback(int result, NdbConnection * pCon, void * threadData);
54 void T3_Callback_1(int result, NdbConnection * pCon, void * threadData);
55 void T3_Callback_2(int result, NdbConnection * pCon, void * threadData);
56 void T3_Callback_3(int result, NdbConnection * pCon, void * threadData);
57 void T4_Callback_1(int result, NdbConnection * pCon, void * threadData);
58 void T4_Callback_2(int result, NdbConnection * pCon, void * threadData);
59 void T4_Callback_3(int result, NdbConnection * pCon, void * threadData);
60 void T5_Callback_1(int result, NdbConnection * pCon, void * threadData);
61 void T5_Callback_2(int result, NdbConnection * pCon, void * threadData);
62 void T5_Callback_3(int result, NdbConnection * pCon, void * threadData);
63 
77 void
78 start_T1(Ndb * pNDB, ThreadData * td){
79 
80  DEBUG2("T1(%.*s): - Starting\n", SUBSCRIBER_NUMBER_LENGTH,
81  td->transactionData.number);
82 
83  int check;
84  NdbConnection * pCON = pNDB->startTransaction();
85  if (pCON != NULL) {
86  NdbOperation *MyOp = pCON->getNdbOperation(SUBSCRIBER_TABLE);
87  if (MyOp != NULL) {
88  MyOp->updateTuple();
89  MyOp->equal(IND_SUBSCRIBER_NUMBER,
90  td->transactionData.number);
91  MyOp->setValue(IND_SUBSCRIBER_LOCATION,
92  (char *)&td->transactionData.location);
93  MyOp->setValue(IND_SUBSCRIBER_CHANGED_BY,
94  td->transactionData.changed_by);
95  MyOp->setValue(IND_SUBSCRIBER_CHANGED_TIME,
96  td->transactionData.changed_time);
97  pCON->executeAsynchPrepare( Commit , T1_Callback, td);
98  } else {
99  CHECK_NULL(MyOp, "T1: getNdbOperation", pCON);
100  }//if
101  } else {
102  error_handler("T1-1: startTranscation",
103  pNDB->getNdbErrorString(),
104  pNDB->getNdbError());
105  }//if
106 }
107 
108 void
109 T1_Callback(int result, NdbConnection * pCON, void * threadData){
110  ThreadData * td = (ThreadData *)threadData;
111 
112  DEBUG2("T1(%.*s): - Completing\n", SUBSCRIBER_NUMBER_LENGTH,
113  td->transactionData.number);
114 
115  CHECK_MINUS_ONE(result, "T1: Commit",
116  pCON);
117  td->pNDB->closeTransaction(pCON);
118  complete_T1(td);
119 }
120 
135 void
136 start_T2(Ndb * pNDB, ThreadData * td){
137 
138  DEBUG3("T2(%.*s, %p): - Starting\n", SUBSCRIBER_NUMBER_LENGTH,
139  td->transactionData.number,
140  td->transactionData.location);
141 
142  int check;
143  NdbRecAttr * check2;
144 
145  NdbConnection * pCON = pNDB->startTransaction();
146  if (pCON == NULL)
147  error_handler("T2-1: startTransaction",
148  pNDB->getNdbErrorString(),
149  pNDB->getNdbError());
150 
151  NdbOperation *MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE);
152  CHECK_NULL(MyOp, "T2: getNdbOperation",
153  pCON);
154 
155  MyOp->readTuple();
156  MyOp->equal(IND_SUBSCRIBER_NUMBER,
157  td->transactionData.number);
158  MyOp->getValue(IND_SUBSCRIBER_LOCATION,
159  (char *)&td->transactionData.location);
160  MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY,
161  td->transactionData.changed_by);
162  MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME,
163  td->transactionData.changed_time);
164  MyOp->getValue(IND_SUBSCRIBER_NAME,
165  td->transactionData.name);
166  pCON->executeAsynchPrepare( Commit, T2_Callback, td );
167 }
168 
169 void
170 T2_Callback(int result, NdbConnection * pCON, void * threadData){
171  ThreadData * td = (ThreadData *)threadData;
172  DEBUG3("T2(%.*s, %p): - Completing\n", SUBSCRIBER_NUMBER_LENGTH,
173  td->transactionData.number,
174  td->transactionData.location);
175 
176  CHECK_MINUS_ONE(result, "T2: Commit", pCON);
177  td->pNDB->closeTransaction(pCON);
178  complete_T2(td);
179 }
180 
198 void
199 start_T3(Ndb * pNDB, ThreadData * td){
200 
201  DEBUG3("T3(%.*s, %.2d): - Starting\n", SUBSCRIBER_NUMBER_LENGTH,
202  td->transactionData.number,
203  td->transactionData.server_id);
204 
205  int check;
206  NdbRecAttr * check2;
207 
208  NdbConnection * pCON = startTransaction(pNDB,
209  td->transactionData.server_id,
210  td->transactionData.number);
211  if (pCON == NULL)
212  error_handler("T3-1: startTranscation",
213  pNDB->getNdbErrorString(),
214  pNDB->getNdbError());
215 
216  NdbOperation *MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE);
217  CHECK_NULL(MyOp, "T3-1: getNdbOperation",
218  pCON);
219 
220  MyOp->readTuple();
221  MyOp->equal(IND_SUBSCRIBER_NUMBER,
222  td->transactionData.number);
223  MyOp->getValue(IND_SUBSCRIBER_LOCATION,
224  (char *)&td->transactionData.location);
225  MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY,
226  td->transactionData.changed_by);
227  MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME,
228  td->transactionData.changed_time);
229  MyOp->getValue(IND_SUBSCRIBER_GROUP,
230  (char *)&td->transactionData.group_id);
231  MyOp->getValue(IND_SUBSCRIBER_SESSIONS,
232  (char *)&td->transactionData.sessions);
233  pCON->executeAsynchPrepare( NoCommit , T3_Callback_1, td);
234 }
235 
236 void
237 T3_Callback_1(int result, NdbConnection * pCON, void * threadData){
238  ThreadData * td = (ThreadData *)threadData;
239  DEBUG3("T3(%.*s, %.2d): - Callback 1\n", SUBSCRIBER_NUMBER_LENGTH,
240  td->transactionData.number,
241  td->transactionData.server_id);
242 
243  CHECK_MINUS_ONE(result, "T3-1: NoCommit", pCON);
244 
245  NdbOperation * MyOp = pCON->getNdbOperation(GROUP_TABLE);
246  CHECK_NULL(MyOp, "T3-2: getNdbOperation",
247  pCON);
248 
249  MyOp->readTuple();
250  MyOp->equal(IND_GROUP_ID,
251  (char*)&td->transactionData.group_id);
252  MyOp->getValue(IND_GROUP_ALLOW_READ,
253  (char *)&td->transactionData.permission);
254  pCON->executeAsynchPrepare( NoCommit, T3_Callback_2, td );
255 }
256 
257 void
258 T3_Callback_2(int result, NdbConnection * pCON, void * threadData){
259  ThreadData * td = (ThreadData *)threadData;
260 
261  CHECK_MINUS_ONE(result, "T3-2: NoCommit", pCON);
262 
263  Uint32 permission = td->transactionData.permission;
264  Uint32 sessions = td->transactionData.sessions;
265  Uint32 server_bit = td->transactionData.server_bit;
266 
267  if(((permission & server_bit) == server_bit) &&
268  ((sessions & server_bit) == server_bit)){
269 
270  memcpy(td->transactionData.suffix,
271  &td->transactionData.number
272  [SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH],
273  SUBSCRIBER_NUMBER_SUFFIX_LENGTH);
274  DEBUG5("T3(%.*s, %.2d): - Callback 2 - reading(%.*s)\n",
275  SUBSCRIBER_NUMBER_LENGTH,
276  td->transactionData.number,
277  td->transactionData.server_id,
278  SUBSCRIBER_NUMBER_SUFFIX_LENGTH,
279  td->transactionData.suffix);
280 
281  /* Operation 3 */
282  NdbOperation * MyOp = pCON->getNdbOperation(SESSION_TABLE);
283  CHECK_NULL(MyOp, "T3-3: getNdbOperation",
284  pCON);
285 
286  MyOp->simpleRead();
287  MyOp->equal(IND_SESSION_SUBSCRIBER,
288  (char*)td->transactionData.number);
289  MyOp->equal(IND_SESSION_SERVER,
290  (char*)&td->transactionData.server_id);
291  MyOp->getValue(IND_SESSION_DATA,
292  (char *)td->transactionData.session_details);
293 
294  /* Operation 4 */
295  MyOp = pCON->getNdbOperation(SERVER_TABLE);
296  CHECK_NULL(MyOp, "T3-4: getNdbOperation",
297  pCON);
298 
299  MyOp->interpretedUpdateTuple();
300  MyOp->equal(IND_SERVER_ID,
301  (char*)&td->transactionData.server_id);
302  MyOp->equal(IND_SERVER_SUBSCRIBER_SUFFIX,
303  (char*)td->transactionData.suffix);
304  MyOp->incValue(IND_SERVER_READS, (uint32)1);
305  td->transactionData.branchExecuted = 1;
306  } else {
307  DEBUG3("T3(%.*s, %.2d): - Callback 2 - no read\n",
308  SUBSCRIBER_NUMBER_LENGTH,
309  td->transactionData.number,
310  td->transactionData.server_id);
311  td->transactionData.branchExecuted = 0;
312  }
313  pCON->executeAsynchPrepare( Commit, T3_Callback_3, td );
314 }
315 
316 void
317 T3_Callback_3(int result, NdbConnection * pCON, void * threadData){
318  ThreadData * td = (ThreadData *)threadData;
319  DEBUG3("T3(%.*s, %.2d): - Completing\n", SUBSCRIBER_NUMBER_LENGTH,
320  td->transactionData.number,
321  td->transactionData.server_id);
322 
323  CHECK_MINUS_ONE(result, "T3-3: Commit", pCON);
324 
325  td->pNDB->closeTransaction(pCON);
326  complete_T3(td);
327 }
328 
346 void
347 start_T4(Ndb * pNDB, ThreadData * td){
348 
349  DEBUG3("T4(%.*s, %.2d): - Starting\n", SUBSCRIBER_NUMBER_LENGTH,
350  td->transactionData.number,
351  td->transactionData.server_id);
352 
353  int check;
354  NdbRecAttr * check2;
355 
356  NdbConnection * pCON = startTransaction(pNDB,
357  td->transactionData.server_id,
358  td->transactionData.number);
359  if (pCON == NULL)
360  error_handler("T4-1: startTranscation",
361  pNDB->getNdbErrorString(),
362  pNDB->getNdbError());
363 
364  NdbOperation *MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE);
365  CHECK_NULL(MyOp, "T4-1: getNdbOperation",
366  pCON);
367 
368  MyOp->interpretedUpdateTuple();
369  MyOp->equal(IND_SUBSCRIBER_NUMBER,
370  td->transactionData.number);
371  MyOp->getValue(IND_SUBSCRIBER_LOCATION,
372  (char *)&td->transactionData.location);
373  MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY,
374  td->transactionData.changed_by);
375  MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME,
376  td->transactionData.changed_time);
377  MyOp->getValue(IND_SUBSCRIBER_GROUP,
378  (char *)&td->transactionData.group_id);
379  MyOp->getValue(IND_SUBSCRIBER_SESSIONS,
380  (char *)&td->transactionData.sessions);
381  MyOp->incValue(IND_SUBSCRIBER_SESSIONS,
382  (uint32)td->transactionData.server_bit);
383  pCON->executeAsynchPrepare( NoCommit , T4_Callback_1, td);
384 }
385 
386 void
387 T4_Callback_1(int result, NdbConnection * pCON, void * threadData){
388  CHECK_MINUS_ONE(result, "T4-1: NoCommit", pCON);
389  ThreadData * td = (ThreadData *)threadData;
390 
391  DEBUG3("T4(%.*s, %.2d): - Callback 1\n",
392  SUBSCRIBER_NUMBER_LENGTH,
393  td->transactionData.number,
394  td->transactionData.server_id);
395 
396 
397  NdbOperation * MyOp = pCON->getNdbOperation(GROUP_TABLE);
398  CHECK_NULL(MyOp, "T4-2: getNdbOperation",
399  pCON);
400 
401  MyOp->readTuple();
402  MyOp->equal(IND_GROUP_ID,
403  (char*)&td->transactionData.group_id);
404  MyOp->getValue(IND_GROUP_ALLOW_INSERT,
405  (char *)&td->transactionData.permission);
406  pCON->executeAsynchPrepare( NoCommit , T4_Callback_2, td);
407 }
408 
409 void
410 T4_Callback_2(int result, NdbConnection * pCON, void * threadData){
411  CHECK_MINUS_ONE(result, "T4-2: NoCommit", pCON);
412  ThreadData * td = (ThreadData *)threadData;
413 
414  Uint32 permission = td->transactionData.permission;
415  Uint32 sessions = td->transactionData.sessions;
416  Uint32 server_bit = td->transactionData.server_bit;
417 
418  if(((permission & server_bit) == server_bit) &&
419  ((sessions & server_bit) == 0)){
420 
421  memcpy(td->transactionData.suffix,
422  &td->transactionData.number
423  [SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH],
424  SUBSCRIBER_NUMBER_SUFFIX_LENGTH);
425 
426  DEBUG5("T4(%.*s, %.2d): - Callback 2 - inserting(%.*s)\n",
427  SUBSCRIBER_NUMBER_LENGTH,
428  td->transactionData.number,
429  td->transactionData.server_id,
430  SUBSCRIBER_NUMBER_SUFFIX_LENGTH,
431  td->transactionData.suffix);
432 
433  /* Operation 3 */
434 
435  NdbOperation * MyOp = pCON->getNdbOperation(SESSION_TABLE);
436  CHECK_NULL(MyOp, "T4-3: getNdbOperation",
437  pCON);
438 
439  MyOp->insertTuple();
440  MyOp->equal(IND_SESSION_SUBSCRIBER,
441  (char*)td->transactionData.number);
442  MyOp->equal(IND_SESSION_SERVER,
443  (char*)&td->transactionData.server_id);
444  MyOp->setValue(SESSION_DATA,
445  (char *)td->transactionData.session_details);
446  /* Operation 4 */
447 
448  /* Operation 5 */
449  MyOp = pCON->getNdbOperation(SERVER_TABLE);
450  CHECK_NULL(MyOp, "T4-5: getNdbOperation",
451  pCON);
452 
453  MyOp->interpretedUpdateTuple();
454  MyOp->equal(IND_SERVER_ID,
455  (char*)&td->transactionData.server_id);
456  MyOp->equal(IND_SERVER_SUBSCRIBER_SUFFIX,
457  (char*)td->transactionData.suffix);
458  MyOp->incValue(IND_SERVER_INSERTS, (uint32)1);
459  td->transactionData.branchExecuted = 1;
460  } else {
461  td->transactionData.branchExecuted = 0;
462  DEBUG5("T4(%.*s, %.2d): - Callback 2 - %s %s\n",
463  SUBSCRIBER_NUMBER_LENGTH,
464  td->transactionData.number,
465  td->transactionData.server_id,
466  ((permission & server_bit) ?
467  "permission - " : "no permission - "),
468  ((sessions & server_bit) ?
469  "in session - " : "no in session - "));
470  }
471 
472  if(!td->transactionData.do_rollback && td->transactionData.branchExecuted){
473  pCON->executeAsynchPrepare(Commit, T4_Callback_3, td);
474  } else {
475  pCON->executeAsynchPrepare(Rollback, T4_Callback_3, td);
476  }
477 }
478 
479 void
480 T4_Callback_3(int result, NdbConnection * pCON, void * threadData){
481  CHECK_MINUS_ONE(result, "T4-3: Commit", pCON);
482  ThreadData * td = (ThreadData *)threadData;
483 
484  DEBUG3("T4(%.*s, %.2d): - Completing\n",
485  SUBSCRIBER_NUMBER_LENGTH,
486  td->transactionData.number,
487  td->transactionData.server_id);
488 
489  td->pNDB->closeTransaction(pCON);
490  complete_T4(td);
491 }
492 
509 void
510 start_T5(Ndb * pNDB, ThreadData * td){
511 
512  DEBUG3("T5(%.*s, %.2d): - Starting\n", SUBSCRIBER_NUMBER_LENGTH,
513  td->transactionData.number,
514  td->transactionData.server_id);
515 
516  int check;
517  NdbRecAttr * check2;
518 
519  NdbConnection * pCON = pNDB->startTransaction();
520  if (pCON == NULL)
521  error_handler("T5-1: startTranscation",
522  pNDB->getNdbErrorString(),
523  pNDB->getNdbError());
524 
525  NdbOperation * MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE);
526  CHECK_NULL(MyOp, "T5-1: getNdbOperation",
527  pCON);
528 
529  MyOp->interpretedUpdateTuple();
530  MyOp->equal(IND_SUBSCRIBER_NUMBER,
531  td->transactionData.number);
532  MyOp->getValue(IND_SUBSCRIBER_LOCATION,
533  (char *)&td->transactionData.location);
534  MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY,
535  td->transactionData.changed_by);
536  MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME,
537  td->transactionData.changed_time);
538  MyOp->getValue(IND_SUBSCRIBER_GROUP,
539  (char *)&td->transactionData.group_id);
540  MyOp->getValue(IND_SUBSCRIBER_SESSIONS,
541  (char *)&td->transactionData.sessions);
542  MyOp->subValue(IND_SUBSCRIBER_SESSIONS,
543  (uint32)td->transactionData.server_bit);
544  pCON->executeAsynchPrepare( NoCommit, T5_Callback_1, td );
545 }
546 
547 void
548 T5_Callback_1(int result, NdbConnection * pCON, void * threadData){
549  CHECK_MINUS_ONE(result, "T5-1: NoCommit", pCON);
550  ThreadData * td = (ThreadData *)threadData;
551 
552  DEBUG3("T5(%.*s, %.2d): - Callback 1\n",
553  SUBSCRIBER_NUMBER_LENGTH,
554  td->transactionData.number,
555  td->transactionData.server_id);
556 
557  NdbOperation * MyOp = pCON->getNdbOperation(GROUP_TABLE);
558  CHECK_NULL(MyOp, "T5-2: getNdbOperation",
559  pCON);
560 
561  MyOp->readTuple();
562  MyOp->equal(IND_GROUP_ID,
563  (char*)&td->transactionData.group_id);
564  MyOp->getValue(IND_GROUP_ALLOW_DELETE,
565  (char *)&td->transactionData.permission);
566  pCON->executeAsynchPrepare( NoCommit, T5_Callback_2, td );
567 }
568 
569 void
570 T5_Callback_2(int result, NdbConnection * pCON, void * threadData){
571  CHECK_MINUS_ONE(result, "T5-2: NoCommit", pCON);
572  ThreadData * td = (ThreadData *)threadData;
573 
574  Uint32 permission = td->transactionData.permission;
575  Uint32 sessions = td->transactionData.sessions;
576  Uint32 server_bit = td->transactionData.server_bit;
577 
578  if(((permission & server_bit) == server_bit) &&
579  ((sessions & server_bit) == server_bit)){
580 
581  memcpy(td->transactionData.suffix,
582  &td->transactionData.number
583  [SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH],
584  SUBSCRIBER_NUMBER_SUFFIX_LENGTH);
585 
586  DEBUG5("T5(%.*s, %.2d): - Callback 2 - deleting(%.*s)\n",
587  SUBSCRIBER_NUMBER_LENGTH,
588  td->transactionData.number,
589  td->transactionData.server_id,
590  SUBSCRIBER_NUMBER_SUFFIX_LENGTH,
591  td->transactionData.suffix);
592 
593  /* Operation 3 */
594  NdbOperation * MyOp = pCON->getNdbOperation(SESSION_TABLE);
595  CHECK_NULL(MyOp, "T5-3: getNdbOperation",
596  pCON);
597 
598  MyOp->deleteTuple();
599  MyOp->equal(IND_SESSION_SUBSCRIBER,
600  (char*)td->transactionData.number);
601  MyOp->equal(IND_SESSION_SERVER,
602  (char*)&td->transactionData.server_id);
603  /* Operation 4 */
604 
605  /* Operation 5 */
606  MyOp = pCON->getNdbOperation(SERVER_TABLE);
607  CHECK_NULL(MyOp, "T5-5: getNdbOperation",
608  pCON);
609 
610  MyOp->interpretedUpdateTuple();
611  MyOp->equal(IND_SERVER_ID,
612  (char*)&td->transactionData.server_id);
613  MyOp->equal(IND_SERVER_SUBSCRIBER_SUFFIX,
614  (char*)td->transactionData.suffix);
615  MyOp->incValue(IND_SERVER_DELETES, (uint32)1);
616  td->transactionData.branchExecuted = 1;
617  } else {
618  td->transactionData.branchExecuted = 0;
619 
620  DEBUG5("T5(%.*s, %.2d): - Callback 2 - no delete - %s %s\n",
621  SUBSCRIBER_NUMBER_LENGTH,
622  td->transactionData.number,
623  td->transactionData.server_id,
624  ((permission & server_bit) ?
625  "permission - " : "no permission - "),
626  ((sessions & server_bit) ?
627  "in session - " : "no in session - "));
628  }
629 
630  if(!td->transactionData.do_rollback && td->transactionData.branchExecuted){
631  pCON->executeAsynchPrepare(Commit, T5_Callback_3, td);
632  } else {
633  pCON->executeAsynchPrepare(Rollback, T5_Callback_3, td);
634  }
635 }
636 
637 void
638 T5_Callback_3(int result, NdbConnection * pCON, void * threadData){
639  CHECK_MINUS_ONE(result, "T5-3: Commit", pCON);
640  ThreadData * td = (ThreadData *)threadData;
641 
642  DEBUG3("T5(%.*s, %.2d): - Completing\n",
643  SUBSCRIBER_NUMBER_LENGTH,
644  td->transactionData.number,
645  td->transactionData.server_id);
646 
647  td->pNDB->closeTransaction(pCON);
648  complete_T5(td);
649 }