~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

Viewing changes to storage/ndb/include/ndbapi/NdbTransaction.hpp

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2003 MySQL AB
 
2
 
 
3
   This program is free software; you can redistribute it and/or modify
 
4
   it under the terms of the GNU General Public License as published by
 
5
   the Free Software Foundation; version 2 of the License.
 
6
 
 
7
   This program is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
   GNU General Public License for more details.
 
11
 
 
12
   You should have received a copy of the GNU General Public License
 
13
   along with this program; if not, write to the Free Software
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
15
 
 
16
#ifndef NdbTransaction_H
 
17
#define NdbTransaction_H
 
18
 
 
19
#include <ndb_types.h>
 
20
#include "NdbError.hpp"
 
21
#include "NdbDictionary.hpp"
 
22
#include "Ndb.hpp"
 
23
#include "NdbOperation.hpp"
 
24
 
 
25
class NdbTransaction;
 
26
class NdbOperation;
 
27
class NdbScanOperation;
 
28
class NdbIndexScanOperation;
 
29
class NdbIndexOperation;
 
30
class NdbApiSignal;
 
31
class Ndb;
 
32
class NdbBlob;
 
33
 
 
34
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
 
35
// to be documented later
 
36
/**
 
37
 * NdbAsynchCallback functions are used when executing asynchronous 
 
38
 * transactions (using NdbTransaction::executeAsynchPrepare, or 
 
39
 * NdbTransaction::executeAsynch).
 
40
 * The functions are called when the execute has finished.
 
41
 * See @ref secAsync for more information.
 
42
 */
 
43
typedef void (* NdbAsynchCallback)(int, NdbTransaction*, void*);
 
44
#endif
 
45
 
 
46
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
 
47
enum AbortOption {
 
48
  DefaultAbortOption = NdbOperation::DefaultAbortOption,
 
49
  CommitIfFailFree = NdbOperation::AbortOnError,         
 
50
  TryCommit = NdbOperation::AbortOnError,
 
51
  AbortOnError= NdbOperation::AbortOnError,
 
52
  CommitAsMuchAsPossible = NdbOperation::AO_IgnoreError,
 
53
  AO_IgnoreError= NdbOperation::AO_IgnoreError
 
54
};
 
55
enum ExecType { 
 
56
  NoExecTypeDef = -1,
 
57
  Prepare,
 
58
  NoCommit,
 
59
  Commit,
 
60
  Rollback
 
61
};
 
62
#endif
 
63
 
 
64
/**
 
65
 * @class NdbTransaction
 
66
 * @brief Represents a transaction.
 
67
 *
 
68
 * A transaction (represented by an NdbTransaction object) 
 
69
 * belongs to an Ndb object and is created using 
 
70
 * Ndb::startTransaction().
 
71
 * A transaction consists of a list of operations 
 
72
 * (represented by NdbOperation, NdbScanOperation, NdbIndexOperation,
 
73
 *  and NdbIndexScanOperation objects). 
 
74
 * Each operation access exactly one table.
 
75
 *
 
76
 * After getting the NdbTransaction object, 
 
77
 * the first step is to get (allocate) an operation given the table name using
 
78
 * one of the methods getNdbOperation(), getNdbScanOperation(),
 
79
 * getNdbIndexOperation(), or getNdbIndexScanOperation().
 
80
 * Then the operation is defined. 
 
81
 * Several operations can be defined on the same 
 
82
 * NdbTransaction object, they will in that case be executed in parallell.
 
83
 * When all operations are defined, the execute()
 
84
 * method sends them to the NDB kernel for execution.
 
85
 *
 
86
 * The execute() method returns when the NDB kernel has 
 
87
 * completed execution of all operations defined before the call to 
 
88
 * execute(). All allocated operations should be properly defined 
 
89
 * before calling execute().
 
90
 *
 
91
 * A call to execute() uses one out of three types of execution:
 
92
 *  -# NdbTransaction::NoCommit  Executes operations without committing them.
 
93
 *  -# NdbTransaction::Commit    Executes remaining operation and commits the 
 
94
 *                         complete transaction
 
95
 *  -# NdbTransaction::Rollback  Rollbacks the entire transaction.
 
96
 *
 
97
 * execute() is equipped with an extra error handling parameter. 
 
98
 * There are two alternatives:
 
99
 * -# NdbTransaction::AbortOnError (default).
 
100
 *    The transaction is aborted if there are any error during the
 
101
 *    execution
 
102
 * -# NdbTransaction::AO_IgnoreError
 
103
 *    Continue execution of transaction even if operation fails
 
104
 *
 
105
 */
 
106
 
 
107
/* FUTURE IMPLEMENTATION:
 
108
 * Later a prepare mode will be added when Ndb supports Prepare-To-Commit
 
109
 * The NdbTransaction can deliver the Transaction Id of the transaction.
 
110
 * After committing a transaction it is also possible to retrieve the 
 
111
 * global transaction checkpoint which the transaction was put in.
 
112
 *
 
113
 * FUTURE IMPLEMENTATION:
 
114
 * There are three methods for acquiring the NdbOperation. 
 
115
 * -# The first method is the normal where a table name is
 
116
 *    provided. In this case the primary key must be supplied through
 
117
 *    the use of the NdbOperation::equal methods on the NdbOperation object.
 
118
 * -# The second method provides the tuple identity of the tuple to be
 
119
 *    read.  The tuple identity contains a table identifier and will
 
120
 *    thus be possible to use to ensure the attribute names provided
 
121
 *    are correct.  If an object-oriented layer is put on top of NDB
 
122
 *    Cluster it is essential that all tables derived from a base
 
123
 *    class has the same attributes with the same type and the same
 
124
 *    name. Thus the application can use the tuple identity and need
 
125
 *    not known the table of the tuple.  As long as the table is
 
126
 *    derived from the known base class everything is ok.
 
127
 *    It is not possible to provide any primary key since it is 
 
128
 *    already supplied with the call to NdbTransaction::getNdbOperation. 
 
129
 * -# The third method is used when a scanned tuple is to be transferred to 
 
130
 *    another transaction. In this case it is not possible to define the 
 
131
 *    primary key since it came along from the scanned tuple.
 
132
 *
 
133
 */
 
134
 
 
135
class NdbTransaction
 
136
{
 
137
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
 
138
  friend class Ndb;
 
139
  friend class NdbOperation;
 
140
  friend class NdbScanOperation;
 
141
  friend class NdbIndexOperation;
 
142
  friend class NdbIndexScanOperation;
 
143
  friend class NdbBlob;
 
144
  friend class ha_ndbcluster;
 
145
#endif
 
146
 
 
147
public:
 
148
 
 
149
  /**
 
150
   * Execution type of transaction
 
151
   */
 
152
  enum ExecType {
 
153
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
 
154
    NoExecTypeDef=
 
155
    ::NoExecTypeDef,            ///< Erroneous type (Used for debugging only)
 
156
    Prepare= ::Prepare,         ///< <i>Missing explanation</i>
 
157
#endif
 
158
    NoCommit=                   ///< Execute the transaction as far as it has
 
159
                                ///< been defined, but do not yet commit it
 
160
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
 
161
    ::NoCommit
 
162
#endif
 
163
    ,Commit=                    ///< Execute and try to commit the transaction
 
164
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
 
165
    ::Commit
 
166
#endif
 
167
    ,Rollback                   ///< Rollback transaction
 
168
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
 
169
    = ::Rollback
 
170
#endif
 
171
  };
 
172
 
 
173
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
 
174
  /**
 
175
   * Convenience method to fetch this transaction's Ndb* object 
 
176
   */
 
177
  Ndb * getNdb() { 
 
178
    return theNdb; 
 
179
  }
 
180
#endif
 
181
 
 
182
#ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
 
183
  /**
 
184
   * Get an NdbOperation for a table.
 
185
   * Note that the operation has to be defined before it is executed.
 
186
   *
 
187
   * @note All operations within the same transaction need to 
 
188
   *       be initialized with this method.
 
189
   * 
 
190
   * @param  aTableName   The table name.
 
191
   * @return  Pointer to an NdbOperation object if successful, otherwise NULL.
 
192
   */
 
193
  NdbOperation* getNdbOperation(const char* aTableName);
 
194
#endif
 
195
 
 
196
  /**
 
197
   * Get an NdbOperation for a table.
 
198
   * Note that the operation has to be defined before it is executed.
 
199
   *
 
200
   * @note All operations within the same transaction need to 
 
201
   *       be initialized with this method.
 
202
   * 
 
203
   * @param  aTable  
 
204
   *         A table object (fetched by NdbDictionary::Dictionary::getTable)
 
205
   * @return  Pointer to an NdbOperation object if successful, otherwise NULL.
 
206
   */
 
207
  NdbOperation* getNdbOperation(const NdbDictionary::Table * aTable);
 
208
 
 
209
#ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
 
210
  /**
 
211
   * Get an operation from NdbScanOperation idlelist and 
 
212
   * get the NdbTransaction object which
 
213
   * was fetched by startTransaction pointing to this operation.
 
214
   *
 
215
   * @param  aTableName  The table name.
 
216
   * @return pointer to an NdbOperation object if successful, otherwise NULL
 
217
   */
 
218
  NdbScanOperation* getNdbScanOperation(const char* aTableName);
 
219
#endif
 
220
 
 
221
  /**
 
222
   * Get an operation from NdbScanOperation idlelist and 
 
223
   * get the NdbTransaction object which
 
224
   * was fetched by startTransaction pointing to this operation.
 
225
   *
 
226
   * @param  aTable  
 
227
   *         A table object (fetched by NdbDictionary::Dictionary::getTable)
 
228
   * @return pointer to an NdbOperation object if successful, otherwise NULL
 
229
   */
 
230
  NdbScanOperation* getNdbScanOperation(const NdbDictionary::Table * aTable);
 
231
 
 
232
#ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
 
233
  /**
 
234
   * Get an operation from NdbIndexScanOperation idlelist and 
 
235
   * get the NdbTransaction object which
 
236
   * was fetched by startTransaction pointing to this operation.
 
237
   *
 
238
   * @param  anIndexName  The index name.
 
239
   * @param  aTableName  The table name.
 
240
   * @return pointer to an NdbOperation object if successful, otherwise NULL
 
241
   */
 
242
  NdbIndexScanOperation* getNdbIndexScanOperation(const char* anIndexName,
 
243
                                                  const char* aTableName);
 
244
  NdbIndexScanOperation* getNdbIndexScanOperation
 
245
  (const NdbDictionary::Index *anIndex, const NdbDictionary::Table *aTable);
 
246
#endif
 
247
  
 
248
  /**
 
249
   * Get an operation from NdbIndexScanOperation idlelist and 
 
250
   * get the NdbTransaction object which
 
251
   * was fetched by startTransaction pointing to this operation.
 
252
   *
 
253
   * @param  anIndex  
 
254
             An index object (fetched by NdbDictionary::Dictionary::getIndex).
 
255
   * @return pointer to an NdbOperation object if successful, otherwise NULL
 
256
   */
 
257
  NdbIndexScanOperation* getNdbIndexScanOperation
 
258
  (const NdbDictionary::Index *anIndex);
 
259
  
 
260
#ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
 
261
  /**
 
262
   * Get an operation from NdbIndexOperation idlelist and 
 
263
   * get the NdbTransaction object that
 
264
   * was fetched by startTransaction pointing to this operation.
 
265
   *
 
266
   * @param   anIndexName   The index name (as created by createIndex).
 
267
   * @param   aTableName    The table name.
 
268
   * @return                Pointer to an NdbIndexOperation object if 
 
269
   *                        successful, otherwise NULL
 
270
   */
 
271
  NdbIndexOperation* getNdbIndexOperation(const char*  anIndexName,
 
272
                                          const char*  aTableName);
 
273
  NdbIndexOperation* getNdbIndexOperation(const NdbDictionary::Index *anIndex,
 
274
                                          const NdbDictionary::Table *aTable);
 
275
#endif
 
276
 
 
277
  /**
 
278
   * Get an operation from NdbIndexOperation idlelist and 
 
279
   * get the NdbTransaction object that
 
280
   * was fetched by startTransaction pointing to this operation.
 
281
   *
 
282
   * @param   anIndex
 
283
   *          An index object (fetched by NdbDictionary::Dictionary::getIndex).
 
284
   * @return              Pointer to an NdbIndexOperation object if 
 
285
   *                      successful, otherwise NULL
 
286
   */
 
287
  NdbIndexOperation* getNdbIndexOperation(const NdbDictionary::Index *anIndex);
 
288
 
 
289
  /** 
 
290
   * @name Execute Transaction
 
291
   * @{
 
292
   */
 
293
 
 
294
  /**
 
295
   * Executes transaction.
 
296
   *
 
297
   * @param execType     Execution type:<br>
 
298
   *                     ExecType::NoCommit executes operations without 
 
299
   *                                        committing them.<br>
 
300
   *                     ExecType::Commit  executes remaining operations and 
 
301
   *                                       commits the complete transaction.<br>
 
302
   *                     ExecType::Rollback rollbacks the entire transaction.
 
303
   * @param abortOption  Handling of error while excuting
 
304
   *                     AbortOnError - Abort transaction if an operation fail
 
305
   *                     IgnoreError  - Accept failing operations
 
306
   * @param force        When operations should be sent to NDB Kernel.
 
307
   *                     (See @ref secAdapt.)
 
308
   *                     - 0: non-force, adaptive algorithm notices it 
 
309
   *                          (default); 
 
310
   *                     - 1: force send, adaptive algorithm notices it; 
 
311
   *                     - 2: non-force, adaptive algorithm do not notice 
 
312
   *                          the send.
 
313
   * @return 0 if successful otherwise -1.
 
314
   */
 
315
  int execute(ExecType execType,
 
316
              NdbOperation::AbortOption = NdbOperation::DefaultAbortOption,
 
317
              int force = 0 );
 
318
#ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
 
319
  int execute(::ExecType execType,
 
320
              ::AbortOption abortOption = ::DefaultAbortOption,
 
321
              int force = 0 ) {
 
322
    return execute ((ExecType)execType,
 
323
                    (NdbOperation::AbortOption)abortOption,
 
324
                    force); }
 
325
#endif
 
326
 
 
327
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
 
328
  // to be documented later
 
329
  /**
 
330
   * Prepare an asynchronous transaction.
 
331
   *
 
332
   * See @ref secAsync for more information on
 
333
   * how to use this method.
 
334
   *
 
335
   * @param execType   Execution type:<br>
 
336
   *        ExecType::NoCommit executes operations without committing them.<br>
 
337
   *        ExecType::Commit   executes remaining operations and commits the 
 
338
   *                           complete transaction.<br>
 
339
   *        ExecType::Rollback rollbacks the entire transaction.
 
340
   * @param callback       A callback method.  This method gets 
 
341
   *                        called when the transaction has been 
 
342
   *                        executed.  See @ref ndbapi_async1.cpp 
 
343
   *                        for an example on how to specify and use 
 
344
   *                        a callback method.
 
345
   * @param anyObject       A void pointer.  This pointer is forwarded to the 
 
346
   *                        callback method and can be used to give 
 
347
   *                        the callback method some data to work on.
 
348
   *                        It is up to the application programmer 
 
349
   *                        to decide on the use of this pointer.
 
350
   * @param abortOption     see @ref execute
 
351
   */
 
352
  void executeAsynchPrepare(ExecType          execType,
 
353
                            NdbAsynchCallback callback,
 
354
                            void*             anyObject,
 
355
                            NdbOperation::AbortOption = NdbOperation::DefaultAbortOption);
 
356
#ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
 
357
  void executeAsynchPrepare(::ExecType       execType,
 
358
                            NdbAsynchCallback callback,
 
359
                            void*             anyObject,
 
360
                            ::AbortOption ao = ::DefaultAbortOption) {
 
361
    executeAsynchPrepare((ExecType)execType, callback, anyObject,
 
362
                         (NdbOperation::AbortOption)ao); }
 
363
#endif
 
364
 
 
365
  /**
 
366
   * Prepare and send an asynchronous transaction.
 
367
   *
 
368
   * This method perform the same action as 
 
369
   * NdbTransaction::executeAsynchPrepare
 
370
   * but also sends the operations to the NDB kernel.
 
371
   *
 
372
   * See NdbTransaction::executeAsynchPrepare for information
 
373
   * about the parameters of this method.
 
374
   *
 
375
   * See @ref secAsync for more information on
 
376
   * how to use this method.
 
377
   */
 
378
  void executeAsynch(ExecType            aTypeOfExec,
 
379
                     NdbAsynchCallback   aCallback,
 
380
                     void*               anyObject,
 
381
                     NdbOperation::AbortOption = NdbOperation::DefaultAbortOption,
 
382
                     int forceSend= 0);
 
383
#ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
 
384
  void executeAsynch(::ExecType         aTypeOfExec,
 
385
                     NdbAsynchCallback   aCallback,
 
386
                     void*               anyObject,
 
387
                     ::AbortOption abortOption= ::DefaultAbortOption,
 
388
                     int forceSend= 0)
 
389
  { executeAsynch((ExecType)aTypeOfExec, aCallback, anyObject,
 
390
                  (NdbOperation::AbortOption)abortOption, forceSend); }
 
391
#endif
 
392
#endif
 
393
  /**
 
394
   * Refresh
 
395
   * Update timeout counter of this transaction 
 
396
   * in the database. If you want to keep the transaction 
 
397
   * active in the database longer than the
 
398
   * transaction abort timeout.
 
399
   * @note It's not advised to take a lock on a record and keep it
 
400
   *       for a extended time since this can impact other transactions.
 
401
   *
 
402
   */
 
403
  int refresh();
 
404
 
 
405
  /**
 
406
   * Close transaction
 
407
   *
 
408
   * @note Equivalent to to calling Ndb::closeTransaction()
 
409
   */
 
410
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
 
411
  /**
 
412
   * @note It is not allowed to call NdbTransaction::close after sending the
 
413
   *       transaction asynchronously before the callback method has 
 
414
   *       been called.
 
415
   *       (The application should keep track of the number of 
 
416
   *       outstanding transactions and wait until all of them 
 
417
   *       has completed before calling NdbTransaction::close).
 
418
   *       If the transaction is not committed it will be aborted.
 
419
   */
 
420
#endif
 
421
  void close();
 
422
 
 
423
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
 
424
  /**
 
425
   * Restart transaction
 
426
   *
 
427
   *   Once a transaction has been completed successfully
 
428
   *     it can be started again wo/ calling closeTransaction/startTransaction
 
429
   *
 
430
   *  @note This method also releases completed operations
 
431
   *
 
432
   *  @note This method does not close open scans, 
 
433
   *        c.f. NdbScanOperation::close()
 
434
   *
 
435
   *  @note This method can only be called _directly_ after commit
 
436
   *        and only if commit is successful
 
437
   */
 
438
  int restart();
 
439
#endif
 
440
 
 
441
  /** @} *********************************************************************/
 
442
 
 
443
  /** 
 
444
   * @name Meta Information
 
445
   * @{
 
446
   */
 
447
 
 
448
  /**
 
449
   * Get global checkpoint identity (GCI) of transaction.
 
450
   *
 
451
   * Each committed transaction belong to a GCI.  
 
452
   * The log for the committed transaction is saved on 
 
453
   * disk when a global checkpoint occurs.
 
454
   * 
 
455
   * Whether or not the global checkpoint with this GCI has been 
 
456
   * saved on disk or not cannot be determined by this method.
 
457
   *
 
458
   * By comparing the GCI of a transaction with the value 
 
459
   * last GCI restored in a restarted NDB Cluster one can determine
 
460
   * whether the transaction was restored or not.
 
461
   *
 
462
   * @note Global Checkpoint Identity is undefined for scan transactions 
 
463
   *       (This is because no updates are performed in scan transactions.)
 
464
   *
 
465
   * @return GCI of transaction or -1 if GCI is not available.
 
466
   *         (Note that there has to be an NdbTransaction::execute call 
 
467
   *         with Ndb::Commit for the GCI to be available.)
 
468
   */
 
469
  int           getGCI();
 
470
                        
 
471
  /**
 
472
   * Get transaction identity.
 
473
   *
 
474
   * @return  Transaction id.
 
475
   */
 
476
  Uint64        getTransactionId();
 
477
 
 
478
  /**
 
479
   * The commit status of the transaction.
 
480
   */
 
481
  enum CommitStatusType { 
 
482
    NotStarted,                   ///< Transaction not yet started
 
483
    Started,                      ///< <i>Missing explanation</i>
 
484
    Committed,                    ///< Transaction has been committed
 
485
    Aborted,                      ///< Transaction has been aborted
 
486
    NeedAbort                     ///< <i>Missing explanation</i>
 
487
  };
 
488
 
 
489
  /**
 
490
   * Get the commit status of the transaction.
 
491
   *
 
492
   * @return  The commit status of the transaction
 
493
   */
 
494
  CommitStatusType commitStatus();
 
495
 
 
496
  /** @} *********************************************************************/
 
497
 
 
498
  /** 
 
499
   * @name Error Handling
 
500
   * @{
 
501
   */
 
502
 
 
503
  /**
 
504
   * Get error object with information about the latest error.
 
505
   *
 
506
   * @return An error object with information about the latest error.
 
507
   */
 
508
  const NdbError & getNdbError() const;
 
509
 
 
510
  /**
 
511
   * Get the latest NdbOperation which had an error. 
 
512
   * This method is used on the NdbTransaction object to find the
 
513
   * NdbOperation causing an error.  
 
514
   * To find more information about the
 
515
   * actual error, use method NdbOperation::getNdbError()
 
516
   * on the returned NdbOperation object.
 
517
   *
 
518
   * @return The NdbOperation causing the latest error.
 
519
   */
 
520
  NdbOperation* getNdbErrorOperation();
 
521
 
 
522
  /** 
 
523
   * Get the method number where the latest error occured.
 
524
   * 
 
525
   * @return Line number where latest error occured.
 
526
   */
 
527
  int getNdbErrorLine();
 
528
 
 
529
  /**
 
530
   * Get completed (i.e. executed) operations of a transaction
 
531
   *
 
532
   * This method should only be used <em>after</em> a transaction 
 
533
   * has been executed.  
 
534
   * - NdbTransaction::getNextCompletedOperation(NULL) returns the
 
535
   *   first NdbOperation object.
 
536
   * - NdbTransaction::getNextCompletedOperation(op) returns the
 
537
   *   NdbOperation object defined after the NdbOperation "op".
 
538
   * 
 
539
   * This method is typically used to fetch all NdbOperation:s of 
 
540
   * a transaction to check for errors (use NdbOperation::getNdbError 
 
541
   * to fetch the NdbError object of an NdbOperation).
 
542
   * 
 
543
   * @note This method should only be used after the transaction has been 
 
544
   *       executed and before the transaction has been closed.
 
545
   * 
 
546
   * @param   op Operation, NULL means get first operation
 
547
   * @return  Operation "after" op
 
548
   */
 
549
  const NdbOperation * getNextCompletedOperation(const NdbOperation * op)const;
 
550
 
 
551
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
 
552
  const NdbOperation* getFirstDefinedOperation()const{return theFirstOpInList;}
 
553
  const NdbOperation* getLastDefinedOperation()const{return theLastOpInList;}
 
554
 
 
555
  /** @} *********************************************************************/
 
556
 
 
557
  /**
 
558
   * Execute the transaction in NoCommit mode if there are any not-yet
 
559
   * executed blob part operations of given types.  Otherwise do
 
560
   * nothing.  The flags argument is bitwise OR of (1 << optype) where
 
561
   * optype comes from NdbOperation::OperationType.  Only the basic PK
 
562
   * ops are used (read, insert, update, delete).
 
563
   */
 
564
  int executePendingBlobOps(Uint8 flags = 0xFF);
 
565
 
 
566
  /**
 
567
   * Get nodeId of TC for this transaction
 
568
   */
 
569
  Uint32 getConnectedNodeId(); // Get Connected node id
 
570
#endif
 
571
 
 
572
private:                                                
 
573
  /**
 
574
   * Release completed operations
 
575
   */
 
576
  void releaseCompletedOperations();
 
577
 
 
578
  typedef Uint64 TimeMillis_t;
 
579
  /**************************************************************************
 
580
   *    These methods are service methods to other classes in the NDBAPI.   *
 
581
   **************************************************************************/
 
582
 
 
583
  /**************************************************************************
 
584
   *    These are the create and delete methods of this class.              *
 
585
   **************************************************************************/
 
586
  NdbTransaction(Ndb* aNdb); 
 
587
  ~NdbTransaction();
 
588
 
 
589
  int init();           // Initialize connection object for new transaction
 
590
 
 
591
  int executeNoBlobs(ExecType execType, 
 
592
                     NdbOperation::AbortOption = NdbOperation::DefaultAbortOption,
 
593
                     int force = 0 );
 
594
  
 
595
  /**
 
596
   * Set Connected node id 
 
597
   * and sequence no
 
598
   */
 
599
  void setConnectedNodeId( Uint32 nodeId, Uint32 sequence); 
 
600
 
 
601
  void          setMyBlockReference( int );       // Set my block refrerence
 
602
  void          setTC_ConnectPtr( Uint32 );       // Sets TC Connect pointer
 
603
  int           getTC_ConnectPtr();               // Gets TC Connect pointer
 
604
  void          setBuddyConPtr(Uint32);           // Sets Buddy Con Ptr
 
605
  Uint32        getBuddyConPtr();                 // Gets Buddy Con Ptr
 
606
  NdbTransaction* next();                         // Returns the next pointer
 
607
  void          next(NdbTransaction*);            // Sets the next pointer
 
608
 
 
609
  enum ConStatusType { 
 
610
    NotConnected,
 
611
    Connecting,
 
612
    Connected,
 
613
    DisConnecting,
 
614
    ConnectFailure
 
615
  };
 
616
  ConStatusType Status();                 // Read the status information
 
617
  void          Status(ConStatusType);    // Set the status information
 
618
 
 
619
  Uint32        get_send_size();                  // Get size to send
 
620
  void          set_send_size(Uint32);            // Set size to send;
 
621
  
 
622
  int  receiveDIHNDBTAMPER(NdbApiSignal* anApiSignal);
 
623
  int  receiveTCSEIZECONF(NdbApiSignal* anApiSignal); 
 
624
  int  receiveTCSEIZEREF(NdbApiSignal* anApiSignal);    
 
625
  int  receiveTCRELEASECONF(NdbApiSignal* anApiSignal); 
 
626
  int  receiveTCRELEASEREF(NdbApiSignal* anApiSignal);  
 
627
  int  receiveTC_COMMITCONF(const class TcCommitConf *);
 
628
  int  receiveTCKEYCONF(const class TcKeyConf *, Uint32 aDataLength);
 
629
  int  receiveTCKEY_FAILCONF(const class TcKeyFailConf *);
 
630
  int  receiveTCKEY_FAILREF(NdbApiSignal* anApiSignal);
 
631
  int  receiveTC_COMMITREF(NdbApiSignal* anApiSignal);                  
 
632
  int  receiveTCROLLBACKCONF(NdbApiSignal* anApiSignal); // Rec TCPREPARECONF ?
 
633
  int  receiveTCROLLBACKREF(NdbApiSignal* anApiSignal);  // Rec TCPREPAREREF ?
 
634
  int  receiveTCROLLBACKREP(NdbApiSignal* anApiSignal);
 
635
  int  receiveTCINDXCONF(const class TcIndxConf *, Uint32 aDataLength);
 
636
  int  receiveTCINDXREF(NdbApiSignal*);
 
637
  int  receiveSCAN_TABREF(NdbApiSignal*);
 
638
  int  receiveSCAN_TABCONF(NdbApiSignal*, const Uint32*, Uint32 len);
 
639
 
 
640
  int   doSend();                       // Send all operations
 
641
  int   sendROLLBACK();                 // Send of an ROLLBACK
 
642
  int   sendTC_HBREP();                 // Send a TCHBREP signal;
 
643
  int   sendCOMMIT();                   // Send a TC_COMMITREQ signal;
 
644
  void  setGCI(int GCI);                // Set the global checkpoint identity
 
645
 
 
646
  int   OpCompleteFailure(NdbOperation*);
 
647
  int   OpCompleteSuccess();
 
648
  void  CompletedOperations();          // Move active ops to list of completed
 
649
 
 
650
  void  OpSent();                       // Operation Sent with success
 
651
  
 
652
  // Free connection related resources and close transaction
 
653
  void          release();              
 
654
 
 
655
  // Release all operations in connection
 
656
  void          releaseOperations();    
 
657
 
 
658
  // Release all cursor operations in connection
 
659
  void releaseOps(NdbOperation*);       
 
660
  void releaseScanOperations(NdbIndexScanOperation*);   
 
661
  bool releaseScanOperation(NdbIndexScanOperation** listhead,
 
662
                            NdbIndexScanOperation** listtail,
 
663
                            NdbIndexScanOperation* op);
 
664
  void releaseExecutedScanOperation(NdbIndexScanOperation*);
 
665
  
 
666
  // Set the transaction identity of the transaction
 
667
  void          setTransactionId(Uint64 aTransactionId);
 
668
 
 
669
  // Indicate something went wrong in the definition phase
 
670
  void          setErrorCode(int anErrorCode);          
 
671
 
 
672
  // Indicate something went wrong in the definition phase
 
673
  void          setOperationErrorCode(int anErrorCode); 
 
674
 
 
675
  // Indicate something went wrong in the definition phase
 
676
  void          setOperationErrorCodeAbort(int anErrorCode, int abortOption = -1);
 
677
 
 
678
  int           checkMagicNumber();                    // Verify correct object
 
679
  NdbOperation* getNdbOperation(const class NdbTableImpl* aTable,
 
680
                                NdbOperation* aNextOp = 0);
 
681
  NdbIndexScanOperation* getNdbScanOperation(const class NdbTableImpl* aTable);
 
682
  NdbIndexOperation* getNdbIndexOperation(const class NdbIndexImpl* anIndex, 
 
683
                                          const class NdbTableImpl* aTable,
 
684
                                          NdbOperation* aNextOp = 0);
 
685
  NdbIndexScanOperation* getNdbIndexScanOperation(const NdbIndexImpl* index,
 
686
                                                  const NdbTableImpl* table);
 
687
  
 
688
  void          handleExecuteCompletion();
 
689
  
 
690
  /****************************************************************************
 
691
   * These are the private variables of this class.
 
692
   ****************************************************************************/
 
693
 
 
694
  Uint32 ptr2int();
 
695
  Uint32 theId;
 
696
 
 
697
  // Keeps track of what the send method should do.
 
698
  enum SendStatusType { 
 
699
    NotInit,  
 
700
    InitState,  
 
701
    sendOperations,  
 
702
    sendCompleted, 
 
703
    sendCOMMITstate, 
 
704
    sendABORT, 
 
705
    sendABORTfail, 
 
706
    sendTC_ROLLBACK,  
 
707
    sendTC_COMMIT, 
 
708
    sendTC_OP       
 
709
  };
 
710
  SendStatusType theSendStatus; 
 
711
  NdbAsynchCallback  theCallbackFunction;    // Pointer to the callback function
 
712
  void*              theCallbackObject;      // The callback object pointer
 
713
  Uint32             theTransArrayIndex;     // Current index in a transaction 
 
714
                                             // array for this object
 
715
  TimeMillis_t       theStartTransTime;      // Start time of the transaction
 
716
 
 
717
  NdbError theError;            // Errorcode on transaction
 
718
  int      theErrorLine;        // Method number of last error in NdbOperation
 
719
  NdbOperation* theErrorOperation; // The NdbOperation where the error occurred
 
720
 
 
721
  Ndb*          theNdb;                      // Pointer to Ndb object      
 
722
  NdbTransaction* theNext;                   // Next pointer. Used in idle list.
 
723
 
 
724
  NdbOperation* theFirstOpInList;           // First operation in defining list.
 
725
  NdbOperation* theLastOpInList;            // Last operation in defining list.
 
726
 
 
727
  NdbOperation* theFirstExecOpInList;       // First executing operation in list
 
728
  NdbOperation* theLastExecOpInList;        // Last executing operation in list.
 
729
 
 
730
 
 
731
  NdbOperation* theCompletedFirstOp;        // First & last operation in completed 
 
732
  NdbOperation* theCompletedLastOp;         // operation list.
 
733
 
 
734
  Uint32        theNoOfOpSent;                          // How many operations have been sent       
 
735
  Uint32        theNoOfOpCompleted;                     // How many operations have completed
 
736
  Uint32        theMyRef;                               // Our block reference          
 
737
  Uint32        theTCConPtr;                            // Transaction Co-ordinator connection pointer.
 
738
  Uint64        theTransactionId;                       // theTransactionId of the transaction
 
739
  Uint32        theGlobalCheckpointId;                  // The gloabl checkpoint identity of the transaction
 
740
  Uint64 *p_latest_trans_gci;                           // Reference to latest gci for connection
 
741
  ConStatusType theStatus;                              // The status of the connection         
 
742
  enum CompletionStatus { 
 
743
    NotCompleted,
 
744
    CompletedSuccess,
 
745
    CompletedFailure,
 
746
    DefinitionFailure
 
747
  } theCompletionStatus;          // The Completion status of the transaction
 
748
  CommitStatusType theCommitStatus;                     // The commit status of the transaction
 
749
  Uint32        theMagicNumber;                         // Magic Number to verify correct object
 
750
 
 
751
  Uint32        thePriority;                            // Transaction Priority
 
752
 
 
753
  enum ReturnType {  ReturnSuccess,  ReturnFailure };
 
754
  ReturnType    theReturnStatus;                        // Did we have any read/update/delete failing
 
755
                                                        // to find the tuple.
 
756
  bool theTransactionIsStarted; 
 
757
  bool theInUseState;
 
758
  bool theSimpleState;
 
759
 
 
760
  enum ListState {  
 
761
    NotInList, 
 
762
    InPreparedList, 
 
763
    InSendList, 
 
764
    InCompletedList 
 
765
  } theListState;
 
766
 
 
767
  Uint32 theDBnode;       // The database node we are connected to  
 
768
  Uint32 theNodeSequence; // The sequence no of the db node
 
769
  bool theReleaseOnClose;
 
770
 
 
771
  /**
 
772
   * handle transaction spanning
 
773
   *   multiple TC/db nodes
 
774
   *
 
775
   * 1) Bitmask with used nodes
 
776
   * 2) Bitmask with nodes failed during op
 
777
   */
 
778
  Uint32 m_db_nodes[2];
 
779
  Uint32 m_failed_db_nodes[2];
 
780
  
 
781
  int report_node_failure(Uint32 id);
 
782
 
 
783
  // Scan operations
 
784
  bool m_waitForReply;     
 
785
  NdbIndexScanOperation* m_theFirstScanOperation;
 
786
  NdbIndexScanOperation* m_theLastScanOperation;
 
787
  
 
788
  NdbIndexScanOperation* m_firstExecutedScanOp;
 
789
 
 
790
  // Scan operations
 
791
  // The operation actually performing the scan
 
792
  NdbScanOperation* theScanningOp; 
 
793
  Uint32 theBuddyConPtr;
 
794
  // optim: any blobs
 
795
  bool theBlobFlag;
 
796
  Uint8 thePendingBlobOps;
 
797
  inline bool hasBlobOperation() { return theBlobFlag; }
 
798
 
 
799
  static void sendTC_COMMIT_ACK(class TransporterFacade *, NdbApiSignal *,
 
800
                                Uint32 transId1, Uint32 transId2, 
 
801
                                Uint32 aBlockRef);
 
802
 
 
803
  void completedFail(const char * s);
 
804
#ifdef VM_TRACE
 
805
  void printState();
 
806
#endif
 
807
  bool checkState_TransId(const Uint32 * transId) const;
 
808
 
 
809
  void remove_list(NdbOperation*& head, NdbOperation*);
 
810
  void define_scan_op(NdbIndexScanOperation*);
 
811
 
 
812
  friend class HugoOperations;
 
813
  friend struct Ndb_free_list_t<NdbTransaction>;
 
814
};
 
815
 
 
816
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
 
817
 
 
818
inline
 
819
Uint32
 
820
NdbTransaction::get_send_size()
 
821
{
 
822
  return 0;
 
823
}
 
824
 
 
825
inline
 
826
void
 
827
NdbTransaction::set_send_size(Uint32 send_size)
 
828
{
 
829
  return;
 
830
}
 
831
 
 
832
#ifdef NDB_NO_DROPPED_SIGNAL
 
833
#include <stdlib.h>
 
834
#endif
 
835
 
 
836
inline
 
837
int
 
838
NdbTransaction::checkMagicNumber()
 
839
{
 
840
  if (theMagicNumber == 0x37412619)
 
841
    return 0;
 
842
  else {
 
843
#ifdef NDB_NO_DROPPED_SIGNAL
 
844
    abort();
 
845
#endif
 
846
    return -1;
 
847
  }
 
848
}
 
849
 
 
850
inline
 
851
bool
 
852
NdbTransaction::checkState_TransId(const Uint32 * transId) const {
 
853
  const Uint32 tTmp1 = transId[0];
 
854
  const Uint32 tTmp2 = transId[1];
 
855
  Uint64 tRecTransId = (Uint64)tTmp1 + ((Uint64)tTmp2 << 32);
 
856
  bool b = theStatus == Connected && theTransactionId == tRecTransId;
 
857
  return b;
 
858
}
 
859
 
 
860
/************************************************************************************************
 
861
void setTransactionId(Uint64 aTransactionId);
 
862
 
 
863
Remark:        Set the transaction identity. 
 
864
************************************************************************************************/
 
865
inline
 
866
void
 
867
NdbTransaction::setTransactionId(Uint64 aTransactionId)
 
868
{
 
869
  theTransactionId = aTransactionId;
 
870
}
 
871
 
 
872
inline
 
873
void                    
 
874
NdbTransaction::setConnectedNodeId(Uint32 aNode, Uint32 aSequenceNo)
 
875
{
 
876
  theDBnode = aNode;
 
877
  theNodeSequence = aSequenceNo;
 
878
}       
 
879
/******************************************************************************
 
880
int getConnectedNodeId();
 
881
 
 
882
Return Value:   Return  theDBnode.
 
883
Remark:         Get Connected node id. 
 
884
******************************************************************************/
 
885
inline
 
886
Uint32                  
 
887
NdbTransaction::getConnectedNodeId()
 
888
{
 
889
  return theDBnode;
 
890
}       
 
891
/******************************************************************************
 
892
void setMyBlockReference(int aBlockRef);
 
893
 
 
894
Parameters:     aBlockRef: The block refrerence.
 
895
Remark:         Set my block refrerence. 
 
896
******************************************************************************/
 
897
inline
 
898
void                    
 
899
NdbTransaction::setMyBlockReference(int aBlockRef)      
 
900
{
 
901
  theMyRef = aBlockRef;
 
902
}
 
903
/******************************************************************************
 
904
void  setTC_ConnectPtr(Uint32 aTCConPtr);
 
905
 
 
906
Parameters:     aTCConPtr: The connection pointer.
 
907
Remark:         Sets TC Connect pointer. 
 
908
******************************************************************************/
 
909
inline
 
910
void                    
 
911
NdbTransaction::setTC_ConnectPtr(Uint32 aTCConPtr)
 
912
{
 
913
  theTCConPtr = aTCConPtr;
 
914
}
 
915
 
 
916
/******************************************************************************
 
917
int  getTC_ConnectPtr();
 
918
 
 
919
Return Value:   Return  theTCConPtr.
 
920
Remark:         Gets TC Connect pointer. 
 
921
******************************************************************************/
 
922
inline
 
923
int                     
 
924
NdbTransaction::getTC_ConnectPtr()
 
925
{
 
926
  return theTCConPtr;
 
927
}
 
928
 
 
929
inline
 
930
void
 
931
NdbTransaction::setBuddyConPtr(Uint32 aBuddyConPtr)
 
932
{
 
933
  theBuddyConPtr = aBuddyConPtr;
 
934
}
 
935
 
 
936
inline
 
937
Uint32 NdbTransaction::getBuddyConPtr()
 
938
{
 
939
  return theBuddyConPtr;
 
940
}
 
941
 
 
942
/******************************************************************************
 
943
NdbTransaction* next();
 
944
 
 
945
inline
 
946
void
 
947
NdbTransaction::setBuddyConPtr(Uint32 aBuddyConPtr)
 
948
{
 
949
  theBuddyConPtr = aBuddyConPtr;
 
950
}
 
951
 
 
952
inline
 
953
Uint32 NdbTransaction::getBuddyConPtr()
 
954
{
 
955
  return theBuddyConPtr;
 
956
}
 
957
 
 
958
Return Value:   Return  next pointer to NdbTransaction object.
 
959
Remark:         Get the next pointer. 
 
960
******************************************************************************/
 
961
inline
 
962
NdbTransaction*
 
963
NdbTransaction::next()
 
964
{
 
965
  return theNext;
 
966
}
 
967
 
 
968
/******************************************************************************
 
969
void next(NdbTransaction aTransaction);
 
970
 
 
971
Parameters:     aTransaction: The connection object. 
 
972
Remark:         Sets the next pointer. 
 
973
******************************************************************************/
 
974
inline
 
975
void
 
976
NdbTransaction::next(NdbTransaction* aTransaction)
 
977
{
 
978
  theNext = aTransaction;
 
979
}
 
980
 
 
981
/******************************************************************************
 
982
ConStatusType  Status();
 
983
 
 
984
Return Value    Return the ConStatusType.       
 
985
Parameters:     aStatus:  The status.
 
986
Remark:         Sets Connect status. 
 
987
******************************************************************************/
 
988
inline
 
989
NdbTransaction::ConStatusType                   
 
990
NdbTransaction::Status()
 
991
{
 
992
  return theStatus;
 
993
}
 
994
 
 
995
/******************************************************************************
 
996
void  Status(ConStatusType aStatus);
 
997
 
 
998
Parameters:     aStatus: The status.
 
999
Remark:         Sets Connect status. 
 
1000
******************************************************************************/
 
1001
inline
 
1002
void                    
 
1003
NdbTransaction::Status( ConStatusType aStatus )
 
1004
{
 
1005
  theStatus = aStatus;
 
1006
}
 
1007
 
 
1008
 
 
1009
/******************************************************************************
 
1010
 void           setGCI();
 
1011
 
 
1012
Remark:         Set global checkpoint identity of the transaction
 
1013
******************************************************************************/
 
1014
inline
 
1015
void
 
1016
NdbTransaction::setGCI(int aGlobalCheckpointId)
 
1017
{
 
1018
  theGlobalCheckpointId = aGlobalCheckpointId;
 
1019
}
 
1020
 
 
1021
/******************************************************************************
 
1022
void OpSent();
 
1023
 
 
1024
Remark:       An operation was sent with success that expects a response.
 
1025
******************************************************************************/
 
1026
inline
 
1027
void 
 
1028
NdbTransaction::OpSent()
 
1029
{
 
1030
  theNoOfOpSent++;
 
1031
}
 
1032
 
 
1033
/******************************************************************************
 
1034
void executePendingBlobOps();
 
1035
******************************************************************************/
 
1036
#include <stdlib.h>
 
1037
inline
 
1038
int
 
1039
NdbTransaction::executePendingBlobOps(Uint8 flags)
 
1040
{
 
1041
  if (thePendingBlobOps & flags) {
 
1042
    // not executeNoBlobs because there can be new ops with blobs
 
1043
    return execute(NoCommit);
 
1044
  }
 
1045
  return 0;
 
1046
}
 
1047
 
 
1048
inline
 
1049
Uint32
 
1050
NdbTransaction::ptr2int(){
 
1051
  return theId;
 
1052
}
 
1053
 
 
1054
typedef NdbTransaction NdbConnection;
 
1055
 
 
1056
#endif // ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
 
1057
 
 
1058
#endif