1 /*
2 Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is also distributed with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have included with MySQL.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25 #ifndef NdbTransaction_H
26 #define NdbTransaction_H
27
28 #include <ndb_types.h>
29 #include "NdbError.hpp"
30 #include "NdbDictionary.hpp"
31 #include "Ndb.hpp"
32 #include "NdbOperation.hpp"
33 #include "NdbIndexScanOperation.hpp"
34
35 class NdbTransaction;
36 class NdbScanOperation;
37 class NdbIndexScanOperation;
38 class NdbIndexOperation;
39 class NdbApiSignal;
40 class Ndb;
41 class NdbBlob;
42 class NdbInterpretedCode;
43 class NdbQueryImpl;
44 class NdbQueryDef;
45 class NdbQuery;
46 class NdbQueryParamValue;
47 class NdbLockHandle;
48
49 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
50 // to be documented later
51 /**
52 * NdbAsynchCallback functions are used when executing asynchronous
53 * transactions (using NdbTransaction::executeAsynchPrepare, or
54 * NdbTransaction::executeAsynch).
55 * The functions are called when the execute has finished.
56 * See @ref secAsync for more information.
57 */
58 typedef void (* NdbAsynchCallback)(int, NdbTransaction*, void*);
59 #endif
60
61 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
62 enum AbortOption {
63 DefaultAbortOption = NdbOperation::DefaultAbortOption,
64 CommitIfFailFree = NdbOperation::AbortOnError,
65 TryCommit = NdbOperation::AbortOnError,
66 AbortOnError= NdbOperation::AbortOnError,
67 CommitAsMuchAsPossible = NdbOperation::AO_IgnoreError,
68 AO_IgnoreError= NdbOperation::AO_IgnoreError
69 };
70 enum ExecType {
71 NoExecTypeDef = -1,
72 Prepare,
73 NoCommit,
74 Commit,
75 Rollback
76 };
77 #endif
78
79 /**
80 * @class NdbTransaction
81 * @brief Represents a transaction.
82 *
83 * A transaction (represented by an NdbTransaction object)
84 * belongs to an Ndb object and is created using
85 * Ndb::startTransaction().
86 * A transaction consists of a list of operations
87 * (represented by NdbOperation, NdbScanOperation, NdbIndexOperation,
88 * and NdbIndexScanOperation objects).
89 * Each operation access exactly one table.
90 *
91 * After getting the NdbTransaction object,
92 * the first step is to get (allocate) an operation given the table name using
93 * one of the methods getNdbOperation(), getNdbScanOperation(),
94 * getNdbIndexOperation(), or getNdbIndexScanOperation().
95 * Then the operation is defined.
96 * Several operations can be defined on the same
97 * NdbTransaction object, they will in that case be executed in parallell.
98 * When all operations are defined, the execute()
99 * method sends them to the NDB kernel for execution.
100 *
101 * The execute() method returns when the NDB kernel has
102 * completed execution of all operations defined before the call to
103 * execute(). All allocated operations should be properly defined
104 * before calling execute().
105 *
106 * A call to execute() uses one out of three types of execution:
107 * -# NdbTransaction::NoCommit Executes operations without committing them.
108 * -# NdbTransaction::Commit Executes remaining operation and commits the
109 * complete transaction
110 * -# NdbTransaction::Rollback Rollbacks the entire transaction.
111 *
112 * execute() is equipped with an extra error handling parameter.
113 * There are two alternatives:
114 * -# NdbTransaction::AbortOnError (default).
115 * The transaction is aborted if there are any error during the
116 * execution
117 * -# NdbTransaction::AO_IgnoreError
118 * Continue execution of transaction even if operation fails
119 *
120 */
121
122 /* FUTURE IMPLEMENTATION:
123 * Later a prepare mode will be added when Ndb supports Prepare-To-Commit
124 * The NdbTransaction can deliver the Transaction Id of the transaction.
125 * After committing a transaction it is also possible to retrieve the
126 * global transaction checkpoint which the transaction was put in.
127 *
128 * FUTURE IMPLEMENTATION:
129 * There are three methods for acquiring the NdbOperation.
130 * -# The first method is the normal where a table name is
131 * provided. In this case the primary key must be supplied through
132 * the use of the NdbOperation::equal methods on the NdbOperation object.
133 * -# The second method provides the tuple identity of the tuple to be
134 * read. The tuple identity contains a table identifier and will
135 * thus be possible to use to ensure the attribute names provided
136 * are correct. If an object-oriented layer is put on top of NDB
137 * Cluster it is essential that all tables derived from a base
138 * class has the same attributes with the same type and the same
139 * name. Thus the application can use the tuple identity and need
140 * not known the table of the tuple. As long as the table is
141 * derived from the known base class everything is ok.
142 * It is not possible to provide any primary key since it is
143 * already supplied with the call to NdbTransaction::getNdbOperation.
144 * -# The third method is used when a scanned tuple is to be transferred to
145 * another transaction. In this case it is not possible to define the
146 * primary key since it came along from the scanned tuple.
147 *
148 */
149
150 class NdbRecord;
151
152 class NdbTransaction
153 {
154 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
155 friend class Ndb;
156 friend class NdbOperation;
157 friend class NdbScanOperation;
158 friend class NdbIndexOperation;
159 friend class NdbIndexScanOperation;
160 friend class NdbBlob;
161 friend class ha_ndbcluster;
162 friend class NdbQueryImpl;
163 friend class NdbQueryOperationImpl;
164 #endif
165
166 public:
167 #ifdef NDBAPI_50_COMPAT
168 enum AbortOption {
169 DefaultAbortOption = NdbOperation::DefaultAbortOption,
170 CommitIfFailFree = NdbOperation::AbortOnError,
171 TryCommit = NdbOperation::AbortOnError,
172 AbortOnError= NdbOperation::AbortOnError,
173 CommitAsMuchAsPossible = NdbOperation::AO_IgnoreError,
174 AO_IgnoreError= NdbOperation::AO_IgnoreError
175 };
176 #endif
177
178
179 /**
180 * Execution type of transaction
181 */
182 enum ExecType {
183 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
184 NoExecTypeDef=
185 ::NoExecTypeDef, ///< Erroneous type (Used for debugging only)
186 Prepare= ::Prepare, ///< <i>Missing explanation</i>
187 #endif
188 NoCommit= ///< Execute the transaction as far as it has
189 ///< been defined, but do not yet commit it
190 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
191 ::NoCommit
192 #endif
193 ,Commit= ///< Execute and try to commit the transaction
194 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
195 ::Commit
196 #endif
197 ,Rollback ///< Rollback transaction
198 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
199 = ::Rollback
200 #endif
201 };
202
203 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
204 /**
205 * Convenience method to fetch this transaction's Ndb* object
206 */
getNdb()207 Ndb * getNdb() {
208 return theNdb;
209 }
210 #endif
211
212 #ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
213 /**
214 * Get an NdbOperation for a table.
215 * Note that the operation has to be defined before it is executed.
216 *
217 * @note All operations within the same transaction need to
218 * be initialized with this method.
219 *
220 * @param aTableName The table name.
221 * @return Pointer to an NdbOperation object if successful, otherwise NULL.
222 */
223 NdbOperation* getNdbOperation(const char* aTableName);
224 #endif
225
226 /**
227 * Get an NdbOperation for a table.
228 * Note that the operation has to be defined before it is executed.
229 *
230 * @note All operations within the same transaction need to
231 * be initialized with this method.
232 *
233 * @param aTable
234 * A table object (fetched by NdbDictionary::Dictionary::getTable)
235 * @return Pointer to an NdbOperation object if successful, otherwise NULL.
236 */
237 NdbOperation* getNdbOperation(const NdbDictionary::Table * aTable);
238
239 #ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
240 /**
241 * Get an operation from NdbScanOperation idlelist and
242 * get the NdbTransaction object which
243 * was fetched by startTransaction pointing to this operation.
244 *
245 * @param aTableName The table name.
246 * @return pointer to an NdbOperation object if successful, otherwise NULL
247 */
248 NdbScanOperation* getNdbScanOperation(const char* aTableName);
249 #endif
250
251 /**
252 * Get an operation from NdbScanOperation idlelist and
253 * get the NdbTransaction object which
254 * was fetched by startTransaction pointing to this operation.
255 *
256 * @param aTable
257 * A table object (fetched by NdbDictionary::Dictionary::getTable)
258 * @return pointer to an NdbOperation object if successful, otherwise NULL
259 */
260 NdbScanOperation* getNdbScanOperation(const NdbDictionary::Table * aTable);
261
262 #ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
263 /**
264 * Get an operation from NdbIndexScanOperation idlelist and
265 * get the NdbTransaction object which
266 * was fetched by startTransaction pointing to this operation.
267 *
268 * @param anIndexName The name of the index to use for scanning
269 * @param aTableName The name of the table to scan
270 * @return pointer to an NdbOperation object if successful, otherwise NULL
271 */
272 NdbIndexScanOperation* getNdbIndexScanOperation(const char* anIndexName,
273 const char* aTableName);
274 NdbIndexScanOperation* getNdbIndexScanOperation
275 (const NdbDictionary::Index *anIndex, const NdbDictionary::Table *aTable);
276 #endif
277
278 /**
279 * Get an operation from NdbIndexScanOperation idlelist and
280 * get the NdbTransaction object which
281 * was fetched by startTransaction pointing to this operation.
282 *
283 * @param anIndex
284 An index object (fetched by NdbDictionary::Dictionary::getIndex).
285 * @return pointer to an NdbOperation object if successful, otherwise NULL
286 */
287 NdbIndexScanOperation* getNdbIndexScanOperation
288 (const NdbDictionary::Index *anIndex);
289
290 #ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
291 /**
292 * Get an operation from NdbIndexOperation idlelist and
293 * get the NdbTransaction object that
294 * was fetched by startTransaction pointing to this operation.
295 *
296 * @param anIndexName The index name (as created by createIndex).
297 * @param aTableName The table name.
298 * @return Pointer to an NdbIndexOperation object if
299 * successful, otherwise NULL
300 */
301 NdbIndexOperation* getNdbIndexOperation(const char* anIndexName,
302 const char* aTableName);
303 NdbIndexOperation* getNdbIndexOperation(const NdbDictionary::Index *anIndex,
304 const NdbDictionary::Table *aTable);
305 #endif
306
307 /**
308 * Get an operation from NdbIndexOperation idlelist and
309 * get the NdbTransaction object that
310 * was fetched by startTransaction pointing to this operation.
311 *
312 * @param anIndex
313 * An index object (fetched by NdbDictionary::Dictionary::getIndex).
314 * @return Pointer to an NdbIndexOperation object if
315 * successful, otherwise NULL
316 */
317 NdbIndexOperation* getNdbIndexOperation(const NdbDictionary::Index *anIndex);
318
319 /**
320 * @name Execute Transaction
321 * @{
322 */
323
324 /**
325 * Executes transaction.
326 *
327 * @param execType Execution type:<br>
328 * ExecType::NoCommit executes operations without
329 * committing them.<br>
330 * ExecType::Commit executes remaining operations and
331 * commits the complete transaction.<br>
332 * ExecType::Rollback rollbacks the entire transaction.
333 * @param abortOption Handling of error while excuting
334 * AbortOnError - Abort transaction if an operation fail
335 * AO_IgnoreError - Accept failing operations
336 * DefaultAbortOption - Use per-operation abort option
337 * @param force When operations should be sent to NDB Kernel.
338 * (See @ref secAdapt.)
339 * - 0: non-force, adaptive algorithm notices it
340 * (default);
341 * - 1: force send, adaptive algorithm notices it;
342 * - 2: non-force, adaptive algorithm do not notice
343 * the send.
344 * @return 0 if successful otherwise -1.
345 */
346 #ifndef NDBAPI_50_COMPAT
347 int execute(ExecType execType,
348 NdbOperation::AbortOption = NdbOperation::DefaultAbortOption,
349 int force = 0 );
350 #ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
execute(::ExecType execType,::AbortOption abortOption=::DefaultAbortOption,int force=0)351 int execute(::ExecType execType,
352 ::AbortOption abortOption = ::DefaultAbortOption,
353 int force = 0 ) {
354 return execute ((ExecType)execType,
355 (NdbOperation::AbortOption)abortOption,
356 force); }
357 #endif
358 #else
359 /**
360 * 50 compability layer
361 * Check 50-docs for sematics
362 */
363
364 int execute(ExecType execType, NdbOperation::AbortOption, int force);
365
execute(NdbTransaction::ExecType execType,NdbTransaction::AbortOption abortOption=AbortOnError,int force=0)366 int execute(NdbTransaction::ExecType execType,
367 NdbTransaction::AbortOption abortOption = AbortOnError,
368 int force = 0)
369 {
370 int ret = execute ((ExecType)execType,
371 (NdbOperation::AbortOption)abortOption,
372 force);
373 if (ret || (abortOption != AO_IgnoreError && theError.code))
374 return -1;
375 return 0;
376 }
377 #endif
378
379 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
380 // to be documented later
381 /**
382 * Prepare an asynchronous transaction.
383 *
384 * See @ref secAsync for more information on
385 * how to use this method.
386 *
387 * @param execType Execution type:<br>
388 * ExecType::NoCommit executes operations without committing them.<br>
389 * ExecType::Commit executes remaining operations and commits the
390 * complete transaction.<br>
391 * ExecType::Rollback rollbacks the entire transaction.
392 * @param callback A callback method. This method gets
393 * called when the transaction has been
394 * executed. See @ref ndbapi_async1.cpp
395 * for an example on how to specify and use
396 * a callback method.
397 * @param anyObject A void pointer. This pointer is forwarded to the
398 * callback method and can be used to give
399 * the callback method some data to work on.
400 * It is up to the application programmer
401 * to decide on the use of this pointer.
402 * @param abortOption see @ref execute
403 */
404 #ifndef NDBAPI_50_COMPAT
405 void executeAsynchPrepare(ExecType execType,
406 NdbAsynchCallback callback,
407 void* anyObject,
408 NdbOperation::AbortOption = NdbOperation::DefaultAbortOption);
409 #ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
executeAsynchPrepare(::ExecType execType,NdbAsynchCallback callback,void * anyObject,::AbortOption ao=::DefaultAbortOption)410 void executeAsynchPrepare(::ExecType execType,
411 NdbAsynchCallback callback,
412 void* anyObject,
413 ::AbortOption ao = ::DefaultAbortOption) {
414 executeAsynchPrepare((ExecType)execType, callback, anyObject,
415 (NdbOperation::AbortOption)ao); }
416 #endif
417 #else
418 /**
419 * 50 compability layer
420 * Check 50-docs for sematics
421 */
422 void executeAsynchPrepare(ExecType execType,
423 NdbAsynchCallback callback,
424 void* anyObject,
425 NdbOperation::AbortOption);
426
executeAsynchPrepare(NdbTransaction::ExecType execType,NdbAsynchCallback callback,void * anyObject,NdbTransaction::AbortOption abortOption=NdbTransaction::AbortOnError)427 void executeAsynchPrepare(NdbTransaction::ExecType execType,
428 NdbAsynchCallback callback,
429 void *anyObject,
430 NdbTransaction::AbortOption abortOption = NdbTransaction::AbortOnError)
431 {
432 executeAsynchPrepare((ExecType)execType, callback, anyObject,
433 (NdbOperation::AbortOption)abortOption);
434 }
435 #endif
436
437 /**
438 * Prepare and send an asynchronous transaction.
439 *
440 * This method perform the same action as
441 * NdbTransaction::executeAsynchPrepare
442 * but also sends the operations to the NDB kernel.
443 *
444 * See NdbTransaction::executeAsynchPrepare for information
445 * about the parameters of this method.
446 *
447 * See @ref secAsync for more information on
448 * how to use this method.
449 */
450 #ifndef NDBAPI_50_COMPAT
451 void executeAsynch(ExecType aTypeOfExec,
452 NdbAsynchCallback aCallback,
453 void* anyObject,
454 NdbOperation::AbortOption = NdbOperation::DefaultAbortOption,
455 int forceSend= 0);
456 #ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
executeAsynch(::ExecType aTypeOfExec,NdbAsynchCallback aCallback,void * anyObject,::AbortOption abortOption=::DefaultAbortOption,int forceSend=0)457 void executeAsynch(::ExecType aTypeOfExec,
458 NdbAsynchCallback aCallback,
459 void* anyObject,
460 ::AbortOption abortOption= ::DefaultAbortOption,
461 int forceSend= 0)
462 { executeAsynch((ExecType)aTypeOfExec, aCallback, anyObject,
463 (NdbOperation::AbortOption)abortOption, forceSend); }
464 #endif
465 #else
466 /**
467 * 50 compability layer
468 * Check 50-docs for sematics
469 */
470 void executeAsynch(ExecType aTypeOfExec,
471 NdbAsynchCallback aCallback,
472 void* anyObject,
473 NdbOperation::AbortOption = NdbOperation::DefaultAbortOption,
474 int forceSend= 0);
executeAsynch(NdbTransaction::ExecType aTypeOfExec,NdbAsynchCallback aCallback,void * anyObject,NdbTransaction::AbortOption abortOption=AbortOnError)475 void executeAsynch(NdbTransaction::ExecType aTypeOfExec,
476 NdbAsynchCallback aCallback,
477 void* anyObject,
478 NdbTransaction::AbortOption abortOption = AbortOnError)
479 {
480 executeAsynch((ExecType)aTypeOfExec, aCallback, anyObject,
481 (NdbOperation::AbortOption)abortOption, 0);
482 }
483 #endif
484 #endif
485
486 /**
487 * Refresh
488 * Update timeout counter of this transaction
489 * in the database. If you want to keep the transaction
490 * active in the database longer than the
491 * transaction abort timeout.
492 * @note It's not advised to take a lock on a record and keep it
493 * for a extended time since this can impact other transactions.
494 *
495 */
496 int refresh();
497
498 /**
499 * Close transaction
500 *
501 * @note Equivalent to to calling Ndb::closeTransaction()
502 */
503 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
504 /**
505 * @note It is not allowed to call NdbTransaction::close after sending the
506 * transaction asynchronously before the callback method has
507 * been called.
508 * (The application should keep track of the number of
509 * outstanding transactions and wait until all of them
510 * has completed before calling NdbTransaction::close).
511 * If the transaction is not committed it will be aborted.
512 */
513 #endif
514 void close();
515
516 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
517 /**
518 * Restart transaction
519 *
520 * Once a transaction has been completed successfully
521 * it can be started again wo/ calling closeTransaction/startTransaction
522 *
523 * @note This method also releases completed operations
524 *
525 * @note This method does not close open scans,
526 * c.f. NdbScanOperation::close()
527 *
528 * @note This method can only be called _directly_ after commit
529 * and only if commit is successful
530 */
531 int restart();
532 #endif
533
534 /** @} *********************************************************************/
535
536 /**
537 * @name Meta Information
538 * @{
539 */
540
541 /**
542 * Get global checkpoint identity (GCI) of transaction.
543 *
544 * Each committed transaction belong to a GCI.
545 * The log for the committed transaction is saved on
546 * disk when a global checkpoint occurs.
547 *
548 * Whether or not the global checkpoint with this GCI has been
549 * saved on disk or not cannot be determined by this method.
550 *
551 * By comparing the GCI of a transaction with the value
552 * last GCI restored in a restarted NDB Cluster one can determine
553 * whether the transaction was restored or not.
554 *
555 * @note Global Checkpoint Identity is undefined for scan transactions
556 * (This is because no updates are performed in scan transactions.)
557 *
558 * @return 0 if GCI is available, and stored in <em>gciptr</em>
559 -1 if GCI is not available.
560 * (Note that there has to be an NdbTransaction::execute call
561 * with Ndb::Commit for the GCI to be available.)
562 */
563 int getGCI(Uint64 * gciptr);
564
565 /**
566 * Deprecated...in favor of getGCI(Uint64*)
567 */
568 int getGCI();
569
570 /**
571 * Get transaction identity.
572 *
573 * @return Transaction id.
574 */
575 Uint64 getTransactionId();
576
577 /**
578 * The commit status of the transaction.
579 */
580 enum CommitStatusType {
581 NotStarted, ///< Transaction not yet started
582 Started, ///< <i>Missing explanation</i>
583 Committed, ///< Transaction has been committed
584 Aborted, ///< Transaction has been aborted
585 NeedAbort ///< <i>Missing explanation</i>
586 };
587
588 /**
589 * Get the commit status of the transaction.
590 *
591 * @return The commit status of the transaction
592 */
593 CommitStatusType commitStatus();
594
595 /** @} *********************************************************************/
596
597 /**
598 * @name Error Handling
599 * @{
600 */
601
602 /**
603 * Get error object with information about the latest error.
604 *
605 * @return An error object with information about the latest error.
606 */
607 const NdbError & getNdbError() const;
608
609 /**
610 * Get the latest NdbOperation which had an error.
611 * This method is used on the NdbTransaction object to find the
612 * NdbOperation causing an error.
613 * To find more information about the
614 * actual error, use method NdbOperation::getNdbError()
615 * on the returned NdbOperation object.
616 *
617 * @return The NdbOperation causing the latest error.
618 * @deprecated Use the const NdbOperation returning variant.
619 */
620 NdbOperation* getNdbErrorOperation();
621
622 /**
623 * Get the latest NdbOperation which had an error.
624 * This method is used on the NdbTransaction object to find the
625 * NdbOperation causing an error.
626 * To find more information about the
627 * actual error, use method NdbOperation::getNdbError()
628 * on the returned NdbOperation object.
629 *
630 * @return The NdbOperation causing the latest error.
631 */
632 const NdbOperation* getNdbErrorOperation() const;
633
634 /**
635 * Get the method number where the latest error occured.
636 *
637 * @return Line number where latest error occured.
638 */
639 int getNdbErrorLine();
640
641 /**
642 * Get completed (i.e. executed) operations of a transaction
643 *
644 * This method should only be used <em>after</em> a transaction
645 * has been executed.
646 * - NdbTransaction::getNextCompletedOperation(NULL) returns the
647 * first NdbOperation object.
648 * - NdbTransaction::getNextCompletedOperation(op) returns the
649 * NdbOperation object defined after the NdbOperation "op".
650 *
651 * This method is typically used to fetch all NdbOperation:s of
652 * a transaction to check for errors (use NdbOperation::getNdbError
653 * to fetch the NdbError object of an NdbOperation).
654 *
655 * @note This method should only be used after the transaction has been
656 * executed and before the transaction has been closed.
657 *
658 * @param op Operation, NULL means get first operation
659 * @return Operation "after" op
660 */
661 const NdbOperation * getNextCompletedOperation(const NdbOperation * op)const;
662
663 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
getFirstDefinedOperation() const664 const NdbOperation* getFirstDefinedOperation()const{return theFirstOpInList;}
getLastDefinedOperation() const665 const NdbOperation* getLastDefinedOperation()const{return theLastOpInList;}
666
667 /** @} *********************************************************************/
668
669 /**
670 * Execute the transaction in NoCommit mode if there are any not-yet
671 * executed blob part operations of given types. Otherwise do
672 * nothing. The flags argument is bitwise OR of (1 << optype) where
673 * optype comes from NdbOperation::OperationType. Only the basic PK
674 * ops are used (read, insert, update, delete).
675 */
676 int executePendingBlobOps(Uint8 flags = 0xFF);
677
678 /**
679 * Get nodeId of TC for this transaction
680 */
681 Uint32 getConnectedNodeId(); // Get Connected node id
682 #endif
683
684 /*
685 * NdbRecord primary key and unique key operations.
686 *
687 * If the key_rec passed in is for a table, the operation will be a primary
688 * key operation. If it is for an index, it will be a unique key operation
689 * using that index.
690 *
691 * The key_row passed in defines the primary or unique key of the affected
692 * tuple, and must remain valid until execute() is called. The key_rec must
693 * include all columns of the key.
694 *
695 * The mask, if != NULL, defines a subset of attributes to read, update, or
696 * insert. Only if (mask[attrId >> 3] & (1<<(attrId & 7))) is set is the
697 * column affected. The mask is copied by the methods, so need not remain
698 * valid after the call returns.
699 *
700 * For unique index operations, the attr_rec must refer to the underlying
701 * table of the index.
702 *
703 * OperationOptions can be used to give finer-grained control of operation
704 * definition. An OperationOptions structure is passed with flags
705 * indicating which operation definition options are present. Not all
706 * operation types support all operation options. See the definition of
707 * the OperationOptions structure for more information on individual options.
708 *
709 * Operation type Supported OperationOptions flags
710 * -------------- --------------------------------
711 * readTuple OO_ABORTOPTION, OO_GETVALUE,
712 * OO_PARTITION_ID, OO_INTERPRETED
713 * insertTuple OO_ABORTOPTION, OO_SETVALUE,
714 * OO_PARTITION_ID, OO_ANYVALUE
715 * updateTuple OO_ABORTOPTION, OO_SETVALUE,
716 * OO_PARTITION_ID, OO_INTERPRETED,
717 * OO_ANYVALUE
718 * writeTuple OO_ABORTOPTION, OO_SETVALUE,
719 * OO_PARTITION_ID, OO_ANYVALUE
720 * deleteTuple OO_ABORTOPTION, OO_GETVALUE,
721 * OO_PARTITION_ID, OO_INTERPRETED,
722 * OO_ANYVALUE
723 *
724 * The sizeOfOptions optional parameter is used to allow this interface
725 * to be backwards compatible with previous definitions of the OperationOptions
726 * structure. If an unusual size is detected by the interface implementation,
727 * it can use this to determine how to interpret the passed OperationOptions
728 * structure. To enable this functionality, the caller should pass
729 * sizeof(NdbOperation::OperationOptions) for this argument.
730 */
731 const NdbOperation *readTuple(const NdbRecord *key_rec, const char *key_row,
732 const NdbRecord *result_rec, char *result_row,
733 NdbOperation::LockMode lock_mode= NdbOperation::LM_Read,
734 const unsigned char *result_mask= 0,
735 const NdbOperation::OperationOptions *opts = 0,
736 Uint32 sizeOfOptions = 0);
737 const NdbOperation *insertTuple(const NdbRecord *key_rec, const char *key_row,
738 const NdbRecord *attr_rec, const char *attr_row,
739 const unsigned char *mask= 0,
740 const NdbOperation::OperationOptions *opts = 0,
741 Uint32 sizeOfOptions = 0);
742 const NdbOperation *insertTuple(const NdbRecord *combined_rec, const char *combined_row,
743 const unsigned char *mask = 0,
744 const NdbOperation::OperationOptions *opts = 0,
745 Uint32 sizeOfOptions = 0);
746 const NdbOperation *updateTuple(const NdbRecord *key_rec, const char *key_row,
747 const NdbRecord *attr_rec, const char *attr_row,
748 const unsigned char *mask= 0,
749 const NdbOperation::OperationOptions *opts = 0,
750 Uint32 sizeOfOptions = 0);
751 const NdbOperation *writeTuple(const NdbRecord *key_rec, const char *key_row,
752 const NdbRecord *attr_rec, const char *attr_row,
753 const unsigned char *mask= 0,
754 const NdbOperation::OperationOptions *opts = 0,
755 Uint32 sizeOfOptions = 0);
756 const NdbOperation *deleteTuple(const NdbRecord *key_rec, const char *key_row,
757 const NdbRecord *result_rec, char *result_row = 0,
758 const unsigned char *result_mask = 0,
759 const NdbOperation::OperationOptions *opts = 0,
760 Uint32 sizeOfOptions = 0);
761
762 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
763 const NdbOperation *refreshTuple(const NdbRecord *key_rec, const char *key_row,
764 const NdbOperation::OperationOptions *opts = 0,
765 Uint32 sizeOfOptions = 0);
766 #endif
767
768 /**
769 * Scan a table, using NdbRecord to read out column data.
770 *
771 * The NdbRecord pointed to by result_record must remain valid until
772 * the scan operation is closed.
773 *
774 * The result_mask pointer is optional, if present only columns for
775 * which the corresponding bit (by attribute id order) in result_mask
776 * is set will be retrieved in the scan. The result_mask is copied
777 * internally, so in contrast to result_record need not be valid at
778 * execute().
779 *
780 * A ScanOptions structure can be passed, specifying extra options. See
781 * the definition of the NdbScanOperation::ScanOptions structure for
782 * more information.
783 *
784 * To enable backwards compatability of this interface, a sizeOfOptions
785 * parameter can be passed. This parameter indicates the size of the
786 * ScanOptions structure at the time the client was compiled, and enables
787 * detection of the use of an old ScanOptions structure. If this
788 * functionality is not required, it can be left set to zero.
789 */
790 NdbScanOperation *
791 scanTable(const NdbRecord *result_record,
792 NdbOperation::LockMode lock_mode= NdbOperation::LM_Read,
793 const unsigned char *result_mask= 0,
794 const NdbScanOperation::ScanOptions *options = 0,
795 Uint32 sizeOfOptions = 0);
796
797 /**
798 * Do an index range scan (optionally ordered) of a table.
799 *
800 * The key_record describes the index to be scanned. It must be a key record
801 * for the index, ie. it must specify (at least) all the key columns of the
802 * index. And it must be created from the index to be scanned (not from the
803 * underlying table).
804 *
805 * The result_record describes the rows to be returned from the scan. For an
806 * ordered index scan, result_record must be a key record for the index to
807 * be scanned, that is it must include at least all of the columns in the
808 * index (the reason is that the full index key is needed by NDBAPI for merge
809 * sorting the ordered rows returned from each fragment). The result_record
810 * must be created from the underlying table, not from the index to be scanned.
811 *
812 * Both the key_record and result_record NdbRecord structures must stay
813 * in-place until the scan operation is closed.
814 *
815 * A single IndexBound can either be specified in this call or in a separate
816 * call to NdbIndexScanOperation::setBound(). To perform a multi range read,
817 * the scan_flags in the ScanOptions structure must include SF_MULTIRANGE.
818 * Additional bounds can then be added using multiple calls to
819 * NdbIndexScanOperation::setBound().
820 *
821 * To specify an equals bound, use the same row pointer for the low_key and
822 * high_key with the low and high inclusive bits set.
823 *
824 * A ScanOptions structure can be passed, specifying extra options. See
825 * the definition of the ScanOptions structure for more information.
826 *
827 * To enable backwards compatability of this interface, a sizeOfOptions
828 * parameter can be passed. This parameter indicates the size of the
829 * ScanOptions structure at the time the client was compiled, and enables
830 * detection of the use of an old ScanOptions structure. If this functionality
831 * is not required, it can be left set to zero.
832 *
833 */
834 NdbIndexScanOperation *
835 scanIndex(const NdbRecord *key_record,
836 const NdbRecord *result_record,
837 NdbOperation::LockMode lock_mode = NdbOperation::LM_Read,
838 const unsigned char *result_mask = 0,
839 const NdbIndexScanOperation::IndexBound *bound = 0,
840 const NdbScanOperation::ScanOptions *options = 0,
841 Uint32 sizeOfOptions = 0);
842
843 /**
844 * Add a prepared NdbQueryDef to transaction for execution.
845 *
846 * If the NdbQueryDef contains parameters,
847 * (built with NdbQueryBilder::paramValue()) the value of these
848 * parameters are specified in the 'paramValue' array. Parameter values
849 * Should be supplied in the same order as the related paramValue's
850 * was defined.
851 */
852 NdbQuery*
853 createQuery(const NdbQueryDef* query,
854 const NdbQueryParamValue paramValue[]= 0,
855 NdbOperation::LockMode lock_mode= NdbOperation::LM_Read);
856
857 /* LockHandle methods */
858 /*
859 * Shared or Exclusive locks taken by read operations in a transaction
860 * are normally held until the transaction commits or aborts.
861 * Shared or Exclusive *read* locks can be released before transaction
862 * commit or abort time by requesting a LockHandle when defining the
863 * read operation. Any time after the read operation has been executed,
864 * the LockHandle can be used to create a new Unlock operation. When
865 * the Unlock operation is executed, the row lock placed by the read
866 * operation will be released.
867 *
868 * The steps are :
869 * 1) Define the primary key read operation in the normal way
870 * with lockmode LM_Read or LM_Exclusive
871 *
872 * 2) Call NdbOperation::getLockHandle() during operation definition
873 * (Or set the OO_LOCKHANDLE operation option when calling
874 * NdbTransaction::readTuple() for NdbRecord)
875 *
876 * 3) Call NdbTransaction::execute()
877 * (Row will be locked from here as normal)
878 *
879 * 4) Use the read data, make zero or more calls to
880 * NdbTransaction::execute() etc.
881 *
882 * 5) Call NdbTransaction::unlock(NdbLockHandle*), passing in the
883 * const LockHandle* from 2) to create an Unlock operation.
884 *
885 * 6) Call NdbTransaction::execute()
886 * (Row will be unlocked from here)
887 *
888 * Notes
889 * - As with other operation types, Unlock operations can be batched.
890 * - Each LockHandle object refers to a lock placed on a row by a single
891 * primary key read operation. A single row in the database may have
892 * concurrent multiple lock holders (of mode LM_Read) and may have
893 * multiple lock holders pending (LM_Exclusive), so releasing the
894 * claim of one lock holder may not result in a change to the
895 * observable lock status of the row.
896 * - LockHandles are supported for Scan lock takeover operations - the
897 * lockhandle must be requested before the locktakeover is executed.
898 * - LockHandles and Unlock operations are not supported for Unique Index
899 * read operations.
900 */
901
902 /* unlock
903 *
904 * This method creates an Unlock operation on the current transaction.
905 * When executed, the Unlock operation will remove the lock referenced
906 * by the passed LockHandle.
907 *
908 * The unlock operation can fail, for example due to the row being
909 * unlocked already. In this scenario, the AbortOption specifies how
910 * this will be handled.
911 * The default is that errors will cause transaction abort.
912 */
913 const NdbOperation* unlock(const NdbLockHandle* lockHandle,
914 NdbOperation::AbortOption ao = NdbOperation::DefaultAbortOption);
915
916 /* releaseLockHandle
917 * This method is used to release a LockHandle object once it
918 * is no longer required.
919 * For NdbRecord primary key read operations, this cannot be
920 * called until the associated read operation has executed.
921 * All LockHandles associated with a transaction are released
922 * when it is closed.
923 */
924 int releaseLockHandle(const NdbLockHandle* lockHandle);
925
926 /* Get maximum number of pending Blob read/write bytes before
927 * an automatic execute() occurs
928 */
929 Uint32 getMaxPendingBlobReadBytes() const;
930 Uint32 getMaxPendingBlobWriteBytes() const;
931
932 /* Set maximum number of pending Blob read/write bytes before
933 * an automatic execute() occurs
934 */
935 void setMaxPendingBlobReadBytes(Uint32 bytes);
936 void setMaxPendingBlobWriteBytes(Uint32 bytes);
937
938 private:
939 /**
940 * Release completed operations
941 */
942 void releaseCompletedOperations();
943 void releaseCompletedQueries();
944
945 typedef Uint64 TimeMillis_t;
946 /**************************************************************************
947 * These methods are service methods to other classes in the NDBAPI. *
948 **************************************************************************/
949
950 /**************************************************************************
951 * These are the create and delete methods of this class. *
952 **************************************************************************/
953 NdbTransaction(Ndb* aNdb);
954 ~NdbTransaction();
955
956 int init(); // Initialize connection object for new transaction
957
958 int executeNoBlobs(ExecType execType,
959 NdbOperation::AbortOption = NdbOperation::DefaultAbortOption,
960 int force = 0 );
961
962 /**
963 * Set Connected node id
964 * and sequence no
965 */
966 void setConnectedNodeId( Uint32 nodeId, Uint32 sequence);
967
968 void setMyBlockReference( int ); // Set my block refrerence
969 void setTC_ConnectPtr( Uint32 ); // Sets TC Connect pointer
970 int getTC_ConnectPtr(); // Gets TC Connect pointer
971 void setBuddyConPtr(Uint32); // Sets Buddy Con Ptr
972 Uint32 getBuddyConPtr(); // Gets Buddy Con Ptr
973 NdbTransaction* next(); // Returns the next pointer
974 void next(NdbTransaction*); // Sets the next pointer
975
976 enum ConStatusType {
977 NotConnected,
978 Connecting,
979 Connected,
980 DisConnecting,
981 ConnectFailure
982 };
983 ConStatusType Status(); // Read the status information
984 void Status(ConStatusType); // Set the status information
985
986 Uint32 get_send_size(); // Get size to send
987 void set_send_size(Uint32); // Set size to send;
988
989 int receiveTCSEIZECONF(const NdbApiSignal* anApiSignal);
990 int receiveTCSEIZEREF(const NdbApiSignal* anApiSignal);
991 int receiveTCRELEASECONF(const NdbApiSignal* anApiSignal);
992 int receiveTCRELEASEREF(const NdbApiSignal* anApiSignal);
993 int receiveTC_COMMITCONF(const class TcCommitConf *, Uint32 len);
994 int receiveTCKEYCONF(const class TcKeyConf *, Uint32 aDataLength);
995 int receiveTCKEY_FAILCONF(const class TcKeyFailConf *);
996 int receiveTCKEY_FAILREF(const NdbApiSignal* anApiSignal);
997 int receiveTC_COMMITREF(const NdbApiSignal* anApiSignal);
998 int receiveTCROLLBACKCONF(const NdbApiSignal* anApiSignal);
999 int receiveTCROLLBACKREF(const NdbApiSignal* anApiSignal);
1000 int receiveTCROLLBACKREP(const NdbApiSignal* anApiSignal);
1001 int receiveTCINDXREF(const NdbApiSignal*);
1002 int receiveSCAN_TABREF(const NdbApiSignal*);
1003 int receiveSCAN_TABCONF(const NdbApiSignal*, const Uint32*, Uint32 len);
1004
1005 int doSend(); // Send all operations
1006 int sendROLLBACK(); // Send of an ROLLBACK
1007 int sendTC_HBREP(); // Send a TCHBREP signal;
1008 int sendCOMMIT(); // Send a TC_COMMITREQ signal;
1009 void setGCI(int GCI); // Set the global checkpoint identity
1010
1011 int OpCompleteFailure();
1012 int OpCompleteSuccess();
1013
1014 void OpSent(); // Operation Sent with success
1015
1016 // Free connection related resources and close transaction
1017 void release();
1018
1019 // Release all operations in connection
1020 void releaseOperations();
1021
1022 // Release all cursor operations in connection
1023 void releaseOps(NdbOperation*);
1024 void releaseQueries(NdbQueryImpl*);
1025 void releaseScanOperations(NdbIndexScanOperation*);
1026 bool releaseScanOperation(NdbIndexScanOperation** listhead,
1027 NdbIndexScanOperation** listtail,
1028 NdbIndexScanOperation* op);
1029 void releaseLockHandles();
1030
1031 // Set the transaction identity of the transaction
1032 void setTransactionId(Uint64 aTransactionId);
1033
1034 // Indicate something went wrong in the definition phase
1035 void setErrorCode(int anErrorCode);
1036
1037 // Indicate something went wrong in the definition phase
1038 void setOperationErrorCode(int anErrorCode);
1039
1040 // Indicate something went wrong in the definition phase
1041 void setOperationErrorCodeAbort(int anErrorCode, int abortOption = -1);
1042
1043 int checkMagicNumber(); // Verify correct object
1044 NdbOperation* getNdbOperation(const class NdbTableImpl* aTable,
1045 NdbOperation* aNextOp = 0,
1046 bool useRec= false);
1047
1048 NdbIndexScanOperation* getNdbScanOperation(const class NdbTableImpl* aTable);
1049 NdbIndexOperation* getNdbIndexOperation(const class NdbIndexImpl* anIndex,
1050 const class NdbTableImpl* aTable,
1051 NdbOperation* aNextOp = 0,
1052 bool useRec= false);
1053 NdbIndexScanOperation* getNdbIndexScanOperation(const NdbIndexImpl* index,
1054 const NdbTableImpl* table);
1055
1056 NdbOperation *setupRecordOp(NdbOperation::OperationType type,
1057 NdbOperation::LockMode lock_mode,
1058 NdbOperation::AbortOption default_ao,
1059 const NdbRecord *key_record,
1060 const char *key_row,
1061 const NdbRecord *attribute_record,
1062 const char *attribute_row,
1063 const unsigned char *mask,
1064 const NdbOperation::OperationOptions *opts,
1065 Uint32 sizeOfOptions,
1066 const NdbLockHandle* lh = 0);
1067
1068 void handleExecuteCompletion();
1069
1070 /****************************************************************************
1071 * These are the private variables of this class.
1072 ****************************************************************************/
1073
1074 Uint32 ptr2int();
1075 Uint32 theId;
1076
1077 // Keeps track of what the send method should do.
1078 enum SendStatusType {
1079 NotInit,
1080 InitState,
1081 sendOperations,
1082 sendCompleted,
1083 sendCOMMITstate,
1084 sendABORT,
1085 sendABORTfail,
1086 sendTC_ROLLBACK,
1087 sendTC_COMMIT,
1088 sendTC_OP
1089 };
1090 SendStatusType theSendStatus;
1091 NdbAsynchCallback theCallbackFunction; // Pointer to the callback function
1092 void* theCallbackObject; // The callback object pointer
1093 Uint32 theTransArrayIndex; // Current index in a transaction
1094 // array for this object
1095 TimeMillis_t theStartTransTime; // Start time of the transaction
1096
1097 NdbError theError; // Errorcode on transaction
1098 int theErrorLine; // Method number of last error in NdbOperation
1099 NdbOperation* theErrorOperation; // The NdbOperation where the error occurred
1100
1101 Ndb* theNdb; // Pointer to Ndb object
1102 NdbTransaction* theNext; // Next pointer. Used in idle list.
1103
1104 NdbOperation* theFirstOpInList; // First operation in defining list.
1105 NdbOperation* theLastOpInList; // Last operation in defining list.
1106
1107 NdbOperation* theFirstExecOpInList; // First executing operation in list
1108 NdbOperation* theLastExecOpInList; // Last executing operation in list.
1109
1110
1111 NdbOperation* theCompletedFirstOp; // First & last operation in completed
1112 NdbOperation* theCompletedLastOp; // operation list.
1113
1114 Uint32 theNoOfOpSent; // How many operations have been sent
1115 Uint32 theNoOfOpCompleted; // How many operations have completed
1116 Uint32 theMyRef; // Our block reference
1117 Uint32 theTCConPtr; // Transaction Co-ordinator connection pointer.
1118 Uint64 theTransactionId; // theTransactionId of the transaction
1119 Uint64 theGlobalCheckpointId; // The gloabl checkpoint identity of the transaction
1120 Uint64 *p_latest_trans_gci; // Reference to latest gci for connection
1121 ConStatusType theStatus; // The status of the connection
1122 enum CompletionStatus {
1123 NotCompleted,
1124 CompletedSuccess,
1125 CompletedFailure,
1126 DefinitionFailure
1127 } theCompletionStatus; // The Completion status of the transaction
1128 CommitStatusType theCommitStatus; // The commit status of the transaction
1129 Uint32 theMagicNumber; // Magic Number to verify correct object
1130 // Current meanings :
1131 // 0x00FE11DC : NdbTransaction not in use
1132 // 0x37412619 : NdbTransaction in use
1133 // 0x00FE11DF : NdbTransaction for scan operation
1134 // scan definition not yet complete
1135 Uint32 thePriority; // Transaction Priority
1136
1137 enum ReturnType { ReturnSuccess, ReturnFailure };
1138 ReturnType theReturnStatus; // Did we have any read/update/delete failing
1139 // to find the tuple.
1140 bool theTransactionIsStarted;
1141 bool theInUseState;
1142 bool theSimpleState;
1143
1144 enum ListState {
1145 NotInList,
1146 InPreparedList,
1147 InSendList,
1148 InCompletedList
1149 } theListState;
1150
1151 Uint32 theDBnode; // The database node we are connected to
1152 Uint32 theNodeSequence; // The sequence no of the db node
1153 bool theReleaseOnClose;
1154
1155 /**
1156 * handle transaction spanning
1157 * multiple TC/db nodes
1158 *
1159 * 1) Bitmask with used nodes
1160 * 2) Bitmask with nodes failed during op
1161 */
1162 Uint32 m_db_nodes[2];
1163 Uint32 m_failed_db_nodes[2];
1164
1165 int report_node_failure(Uint32 id);
1166
1167 // Scan operations
1168 bool m_waitForReply;
1169 NdbIndexScanOperation* m_theFirstScanOperation;
1170 NdbIndexScanOperation* m_theLastScanOperation;
1171
1172 NdbIndexScanOperation* m_firstExecutedScanOp;
1173
1174 // Scan operations or queries:
1175 // The operation or query actually performing the scan.
1176 // (Only one of theScanningOp/m_scanningQuery be non-NULL,
1177 // which indirectly indicates the type)
1178 NdbScanOperation* theScanningOp;
1179
1180 Uint32 theBuddyConPtr;
1181 // optim: any blobs
1182 bool theBlobFlag;
1183 Uint8 thePendingBlobOps;
1184 Uint32 maxPendingBlobReadBytes;
1185 Uint32 maxPendingBlobWriteBytes;
1186 Uint32 pendingBlobReadBytes;
1187 Uint32 pendingBlobWriteBytes;
hasBlobOperation()1188 inline bool hasBlobOperation() { return theBlobFlag; }
1189
1190 static void sendTC_COMMIT_ACK(class NdbImpl *, NdbApiSignal *,
1191 Uint32 transId1, Uint32 transId2,
1192 Uint32 aBlockRef);
1193
1194 void completedFail(const char * s);
1195 #ifdef VM_TRACE
1196 void printState();
1197 #endif
1198 bool checkState_TransId(const Uint32 * transId) const;
1199
1200 void remove_list(NdbOperation*& head, NdbOperation*);
1201 void define_scan_op(NdbIndexScanOperation*);
1202
1203 NdbLockHandle* m_theFirstLockHandle;
1204 NdbLockHandle* m_theLastLockHandle;
1205
1206 NdbLockHandle* getLockHandle();
1207
1208 friend class HugoOperations;
1209 friend struct Ndb_free_list_t<NdbTransaction>;
1210
1211 NdbTransaction(const NdbTransaction&); // Not impl.
1212 NdbTransaction&operator=(const NdbTransaction&);
1213
1214 // Query operation (aka multicursor)
1215 NdbQueryImpl* m_firstQuery; // First query in defining list.
1216 NdbQueryImpl* m_firstExecQuery; // First query to send for execution
1217 NdbQueryImpl* m_firstActiveQuery; // First query actively executing, or completed
1218
1219 // Scan operations or queries:
1220 // The operation or query actually performing the scan.
1221 // (Only one of theScanningOp/m_scanningQuery be non-NULL,
1222 // which indirectly indicates the type)
1223 NdbQueryImpl* m_scanningQuery;
1224
1225 Uint32 m_tcRef;
1226 };
1227
1228 #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
1229
1230 inline
1231 Uint32
get_send_size()1232 NdbTransaction::get_send_size()
1233 {
1234 return 0;
1235 }
1236
1237 inline
1238 void
set_send_size(Uint32 send_size)1239 NdbTransaction::set_send_size(Uint32 send_size)
1240 {
1241 (void)send_size; //unused
1242 return;
1243 }
1244
1245 #ifdef NDB_NO_DROPPED_SIGNAL
1246 #include <stdlib.h>
1247 #endif
1248
1249 inline
1250 int
checkMagicNumber()1251 NdbTransaction::checkMagicNumber()
1252 {
1253 if (theMagicNumber == 0x37412619)
1254 return 0;
1255 else {
1256 #ifdef NDB_NO_DROPPED_SIGNAL
1257 abort();
1258 #endif
1259 return -1;
1260 }
1261 }
1262
1263 inline
1264 bool
checkState_TransId(const Uint32 * transId) const1265 NdbTransaction::checkState_TransId(const Uint32 * transId) const {
1266 const Uint32 tTmp1 = transId[0];
1267 const Uint32 tTmp2 = transId[1];
1268 Uint64 tRecTransId = (Uint64)tTmp1 + ((Uint64)tTmp2 << 32);
1269 bool b = theStatus == Connected && theTransactionId == tRecTransId;
1270 return b;
1271 }
1272
1273 /************************************************************************************************
1274 void setTransactionId(Uint64 aTransactionId);
1275
1276 Remark: Set the transaction identity.
1277 ************************************************************************************************/
1278 inline
1279 void
setTransactionId(Uint64 aTransactionId)1280 NdbTransaction::setTransactionId(Uint64 aTransactionId)
1281 {
1282 theTransactionId = aTransactionId;
1283 }
1284
1285 inline
1286 void
setConnectedNodeId(Uint32 aNode,Uint32 aSequenceNo)1287 NdbTransaction::setConnectedNodeId(Uint32 aNode, Uint32 aSequenceNo)
1288 {
1289 theDBnode = aNode;
1290 theNodeSequence = aSequenceNo;
1291 }
1292 /******************************************************************************
1293 int getConnectedNodeId();
1294
1295 Return Value: Return theDBnode.
1296 Remark: Get Connected node id.
1297 ******************************************************************************/
1298 inline
1299 Uint32
getConnectedNodeId()1300 NdbTransaction::getConnectedNodeId()
1301 {
1302 return theDBnode;
1303 }
1304 /******************************************************************************
1305 void setMyBlockReference(int aBlockRef);
1306
1307 Parameters: aBlockRef: The block refrerence.
1308 Remark: Set my block refrerence.
1309 ******************************************************************************/
1310 inline
1311 void
setMyBlockReference(int aBlockRef)1312 NdbTransaction::setMyBlockReference(int aBlockRef)
1313 {
1314 theMyRef = aBlockRef;
1315 }
1316 /******************************************************************************
1317 void setTC_ConnectPtr(Uint32 aTCConPtr);
1318
1319 Parameters: aTCConPtr: The connection pointer.
1320 Remark: Sets TC Connect pointer.
1321 ******************************************************************************/
1322 inline
1323 void
setTC_ConnectPtr(Uint32 aTCConPtr)1324 NdbTransaction::setTC_ConnectPtr(Uint32 aTCConPtr)
1325 {
1326 theTCConPtr = aTCConPtr;
1327 }
1328
1329 /******************************************************************************
1330 int getTC_ConnectPtr();
1331
1332 Return Value: Return theTCConPtr.
1333 Remark: Gets TC Connect pointer.
1334 ******************************************************************************/
1335 inline
1336 int
getTC_ConnectPtr()1337 NdbTransaction::getTC_ConnectPtr()
1338 {
1339 return theTCConPtr;
1340 }
1341
1342 inline
1343 void
setBuddyConPtr(Uint32 aBuddyConPtr)1344 NdbTransaction::setBuddyConPtr(Uint32 aBuddyConPtr)
1345 {
1346 theBuddyConPtr = aBuddyConPtr;
1347 }
1348
1349 inline
getBuddyConPtr()1350 Uint32 NdbTransaction::getBuddyConPtr()
1351 {
1352 return theBuddyConPtr;
1353 }
1354
1355 /******************************************************************************
1356 NdbTransaction* next();
1357
1358 inline
1359 void
1360 NdbTransaction::setBuddyConPtr(Uint32 aBuddyConPtr)
1361 {
1362 theBuddyConPtr = aBuddyConPtr;
1363 }
1364
1365 inline
1366 Uint32 NdbTransaction::getBuddyConPtr()
1367 {
1368 return theBuddyConPtr;
1369 }
1370
1371 Return Value: Return next pointer to NdbTransaction object.
1372 Remark: Get the next pointer.
1373 ******************************************************************************/
1374 inline
1375 NdbTransaction*
next()1376 NdbTransaction::next()
1377 {
1378 return theNext;
1379 }
1380
1381 /******************************************************************************
1382 void next(NdbTransaction aTransaction);
1383
1384 Parameters: aTransaction: The connection object.
1385 Remark: Sets the next pointer.
1386 ******************************************************************************/
1387 inline
1388 void
next(NdbTransaction * aTransaction)1389 NdbTransaction::next(NdbTransaction* aTransaction)
1390 {
1391 theNext = aTransaction;
1392 }
1393
1394 /******************************************************************************
1395 ConStatusType Status();
1396
1397 Return Value Return the ConStatusType.
1398 Parameters: aStatus: The status.
1399 Remark: Sets Connect status.
1400 ******************************************************************************/
1401 inline
1402 NdbTransaction::ConStatusType
Status()1403 NdbTransaction::Status()
1404 {
1405 return theStatus;
1406 }
1407
1408 /******************************************************************************
1409 void Status(ConStatusType aStatus);
1410
1411 Parameters: aStatus: The status.
1412 Remark: Sets Connect status.
1413 ******************************************************************************/
1414 inline
1415 void
Status(ConStatusType aStatus)1416 NdbTransaction::Status( ConStatusType aStatus )
1417 {
1418 theStatus = aStatus;
1419 }
1420
1421
1422 /******************************************************************************
1423 void OpSent();
1424
1425 Remark: An operation was sent with success that expects a response.
1426 ******************************************************************************/
1427 inline
1428 void
OpSent()1429 NdbTransaction::OpSent()
1430 {
1431 theNoOfOpSent++;
1432 }
1433
1434 /******************************************************************************
1435 void executePendingBlobOps();
1436 ******************************************************************************/
1437 inline
1438 int
executePendingBlobOps(Uint8 flags)1439 NdbTransaction::executePendingBlobOps(Uint8 flags)
1440 {
1441 if (thePendingBlobOps & flags) {
1442 // not executeNoBlobs because there can be new ops with blobs
1443 return execute(NoCommit);
1444 }
1445 return 0;
1446 }
1447
1448 inline
1449 Uint32
ptr2int()1450 NdbTransaction::ptr2int(){
1451 return theId;
1452 }
1453
1454 typedef NdbTransaction NdbConnection;
1455
1456 #endif // ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
1457
1458 #endif
1459