~ubuntu-branches/ubuntu/trusty/drizzle/trusty

« back to all changes in this revision

Viewing changes to drizzled/transaction_services.h

  • Committer: Bazaar Package Importer
  • Author(s): Monty Taylor
  • Date: 2010-11-12 12:26:01 UTC
  • mfrom: (1.1.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20101112122601-myppfj3tfmlkccuq
Tags: upstream-2010.11.03
ImportĀ upstreamĀ versionĀ 2010.11.03

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
#ifndef DRIZZLED_TRANSACTION_SERVICES_H
26
26
#define DRIZZLED_TRANSACTION_SERVICES_H
27
27
 
 
28
#include "drizzled/atomics.h"
 
29
#include "drizzled/message/transaction.pb.h"
 
30
 
28
31
namespace drizzled
29
32
{
30
33
 
33
36
{
34
37
  class MonitoredInTransaction;
35
38
  class XaResourceManager;
 
39
  class XaStorageEngine;
36
40
  class TransactionalStorageEngine;
37
41
}
38
42
 
39
43
class Session;
40
44
class NamedSavepoint;
 
45
class Field;
41
46
 
42
47
/**
43
48
 * This is a class which manages the XA transaction processing
46
51
class TransactionServices
47
52
{
48
53
public:
49
 
  /**
50
 
   * Constructor
51
 
   */
52
 
  TransactionServices() {}
 
54
  static const size_t DEFAULT_RECORD_SIZE= 100;
 
55
  
 
56
  TransactionServices();
53
57
 
54
58
  /**
55
59
   * Singleton method
60
64
    static TransactionServices transaction_services;
61
65
    return transaction_services;
62
66
  }
 
67
 
 
68
  /**
 
69
   * Returns true if the transaction manager should construct
 
70
   * Transaction and Statement messages, false otherwise.
 
71
   */
 
72
  bool shouldConstructMessages();
 
73
  /**
 
74
   * Method which returns the active Transaction message
 
75
   * for the supplied Session.  If one is not found, a new Transaction
 
76
   * message is allocated, initialized, and returned. It is possible that
 
77
   * we may want to NOT increment the transaction id for a new Transaction
 
78
   * object (e.g., splitting up Transactions into smaller chunks). The
 
79
   * should_inc_trx_id flag controls if we do this.
 
80
   *
 
81
   * @param in_session The session processing the transaction
 
82
   * @param should_inc_trx_id If true, increments the transaction id for a new trx
 
83
   */
 
84
  message::Transaction *getActiveTransactionMessage(Session *in_session,
 
85
                                                    bool should_inc_trx_id= true);
 
86
  /** 
 
87
   * Method which attaches a transaction context
 
88
   * the supplied transaction based on the supplied Session's
 
89
   * transaction information.  This method also ensure the
 
90
   * transaction message is attached properly to the Session object
 
91
   *
 
92
   * @param in_transaction The transaction message to initialize
 
93
   * @param in_session The Session processing this transaction
 
94
   * @param should_inc_trx_id If true, increments the transaction id for a new trx
 
95
   */
 
96
  void initTransactionMessage(message::Transaction &in_transaction,
 
97
                              Session *in_session,
 
98
                              bool should_inc_trx_id);
 
99
  /** 
 
100
   * Helper method which finalizes data members for the 
 
101
   * supplied transaction's context.
 
102
   *
 
103
   * @param in_transaction The transaction message to finalize 
 
104
   * @param in_session The Session processing this transaction
 
105
   */
 
106
  void finalizeTransactionMessage(message::Transaction &in_transaction, Session *in_session);
 
107
  /**
 
108
   * Helper method which deletes transaction memory and
 
109
   * unsets Session's transaction and statement messages.
 
110
   */
 
111
  void cleanupTransactionMessage(message::Transaction *in_transaction,
 
112
                                 Session *in_session);
 
113
 
 
114
  /**
 
115
   * Helper method which initializes a Statement message
 
116
   *
 
117
   * @param statement The statement to initialize
 
118
   * @param in_type The type of the statement
 
119
   * @param in_session The session processing this statement
 
120
   */
 
121
  void initStatementMessage(message::Statement &statement,
 
122
                            message::Statement::Type in_type,
 
123
                            Session *in_session);
 
124
  /**
 
125
   * Finalizes a Statement message and sets the Session's statement
 
126
   * message to NULL.
 
127
   *
 
128
   * @param statement The statement to initialize
 
129
   * @param in_session The session processing this statement
 
130
   */
 
131
  void finalizeStatementMessage(message::Statement &statement,
 
132
                                Session *in_session);
 
133
  /** Helper method which returns an initialized Statement message for methods
 
134
   * doing insertion of data.
 
135
   *
 
136
   * @param[in] in_session Pointer to the Session doing the processing
 
137
   * @param[in] in_table Pointer to the Table object being inserted into
 
138
   * @param[out] next_segment_id The next Statement segment id to be used
 
139
   */
 
140
  message::Statement &getInsertStatement(Session *in_session,
 
141
                                         Table *in_table,
 
142
                                         uint32_t *next_segment_id);
 
143
 
 
144
  /**
 
145
   * Helper method which initializes the header message for
 
146
   * insert operations.
 
147
   *
 
148
   * @param[in,out] statement Statement message container to modify
 
149
   * @param[in] in_session Pointer to the Session doing the processing
 
150
   * @param[in] in_table Pointer to the Table being inserted into
 
151
   */
 
152
  void setInsertHeader(message::Statement &statement,
 
153
                       Session *in_session,
 
154
                       Table *in_table);
 
155
  /**
 
156
   * Helper method which returns an initialized Statement
 
157
   * message for methods doing updates of data.
 
158
   *
 
159
   * @param[in] in_session Pointer to the Session doing the processing
 
160
   * @param[in] in_table Pointer to the Table object being updated
 
161
   * @param[in] old_record Pointer to the old data in the record
 
162
   * @param[in] new_record Pointer to the new data in the record
 
163
   * @param[out] next_segment_id The next Statement segment id to be used
 
164
   */
 
165
  message::Statement &getUpdateStatement(Session *in_session,
 
166
                                         Table *in_table,
 
167
                                         const unsigned char *old_record, 
 
168
                                         const unsigned char *new_record,
 
169
                                         uint32_t *next_segment_id);
 
170
  /**
 
171
   * Helper method which initializes the header message for
 
172
   * update operations.
 
173
   *
 
174
   * @param[in,out] statement Statement message container to modify
 
175
   * @param[in] in_session Pointer to the Session doing the processing
 
176
   * @param[in] in_table Pointer to the Table being updated
 
177
   * @param[in] old_record Pointer to the old data in the record
 
178
   * @param[in] new_record Pointer to the new data in the record
 
179
   */
 
180
  void setUpdateHeader(message::Statement &statement,
 
181
                       Session *in_session,
 
182
                       Table *in_table,
 
183
                       const unsigned char *old_record, 
 
184
                       const unsigned char *new_record);
 
185
  /**
 
186
   * Helper method which returns an initialized Statement
 
187
   * message for methods doing deletion of data.
 
188
   *
 
189
   * @param[in] in_session Pointer to the Session doing the processing
 
190
   * @param[in] in_table Pointer to the Table object being deleted from
 
191
   * @param[out] next_segment_id The next Statement segment id to be used
 
192
   */
 
193
  message::Statement &getDeleteStatement(Session *in_session,
 
194
                                         Table *in_table,
 
195
                                         uint32_t *next_segment_id);
 
196
 
 
197
  /**
 
198
   * Helper method which initializes the header message for
 
199
   * insert operations.
 
200
   *
 
201
   * @param[in,out] statement Statement message container to modify
 
202
   * @param[in] in_session Pointer to the Session doing the processing
 
203
   * @param[in] in_table Pointer to the Table being deleted from
 
204
   */
 
205
  void setDeleteHeader(message::Statement &statement,
 
206
                       Session *in_session,
 
207
                       Table *in_table);
 
208
  /** 
 
209
   * Commits a normal transaction (see above) and pushes the transaction
 
210
   * message out to the replicators.
 
211
   *
 
212
   * @param in_session Pointer to the Session committing the transaction
 
213
   */
 
214
  int commitTransactionMessage(Session *in_session);
 
215
  /** 
 
216
   * Marks the current active transaction message as being rolled back and
 
217
   * pushes the transaction message out to replicators.
 
218
   *
 
219
   * @param in_session Pointer to the Session committing the transaction
 
220
   */
 
221
  void rollbackTransactionMessage(Session *in_session);
 
222
  /**
 
223
   * Creates a new InsertRecord GPB message and pushes it to
 
224
   * replicators.
 
225
   *
 
226
   * @param in_session Pointer to the Session which has inserted a record
 
227
   * @param in_table Pointer to the Table containing insert information
 
228
   *
 
229
   * Grr, returning "true" here on error because of the cursor
 
230
   * reversed bool return crap...fix that.
 
231
   */
 
232
  bool insertRecord(Session *in_session, Table *in_table);
 
233
  /**
 
234
   * Creates a new UpdateRecord GPB message and pushes it to
 
235
   * replicators.
 
236
   *
 
237
   * @param in_session Pointer to the Session which has updated a record
 
238
   * @param in_table Pointer to the Table containing update information
 
239
   * @param old_record Pointer to the raw bytes representing the old record/row
 
240
   * @param new_record Pointer to the raw bytes representing the new record/row 
 
241
   */
 
242
  void updateRecord(Session *in_session, 
 
243
                    Table *in_table, 
 
244
                    const unsigned char *old_record, 
 
245
                    const unsigned char *new_record);
 
246
  /**
 
247
   * Creates a new DeleteRecord GPB message and pushes it to
 
248
   * replicators.
 
249
   *
 
250
   * @param in_session Pointer to the Session which has deleted a record
 
251
   * @param in_table Pointer to the Table containing delete information
 
252
   * @param use_update_record If true, uses the values from the update row instead
 
253
   */
 
254
  void deleteRecord(Session *in_session, Table *in_table, bool use_update_record= false);
 
255
 
 
256
  /**
 
257
   * Used to undo effects of a failed statement.
 
258
   *
 
259
   * An SQL statement, like an UPDATE, that affects multiple rows could
 
260
   * potentially fail mid-way through processing the rows. In such a case,
 
261
   * the successfully modified rows that preceeded the failing row would
 
262
   * have been added to the Statement message. This method is used for
 
263
   * rolling back that change.
 
264
   *
 
265
   * @note
 
266
   * This particular failure is seen on column constraint violations
 
267
   * during a multi-row UPDATE and a multi-row INSERT..SELECT.
 
268
   *
 
269
   * @param in_session Pointer to the Session containing the Statement
 
270
   * @param count The number of records to remove from Statement.
 
271
   *
 
272
   * @retval true Successfully removed 'count' records
 
273
   * @retval false Failure
 
274
   */
 
275
  bool removeStatementRecords(Session *in_session, uint32_t count);
 
276
 
 
277
  /**
 
278
   * Creates a CreateSchema Statement GPB message and adds it
 
279
   * to the Session's active Transaction GPB message for pushing
 
280
   * out to the replicator streams.
 
281
   *
 
282
   * @param[in] in_session Pointer to the Session which issued the statement
 
283
   * @param[in] schema message::Schema message describing new schema
 
284
   */
 
285
  void createSchema(Session *in_session, const message::Schema &schema);
 
286
  /**
 
287
   * Creates a DropSchema Statement GPB message and adds it
 
288
   * to the Session's active Transaction GPB message for pushing
 
289
   * out to the replicator streams.
 
290
   *
 
291
   * @param[in] in_session Pointer to the Session which issued the statement
 
292
   * @param[in] schema_name message::Schema message describing new schema
 
293
   */
 
294
  void dropSchema(Session *in_session, const std::string &schema_name);
 
295
  /**
 
296
   * Creates a CreateTable Statement GPB message and adds it
 
297
   * to the Session's active Transaction GPB message for pushing
 
298
   * out to the replicator streams.
 
299
   *
 
300
   * @param[in] in_session Pointer to the Session which issued the statement
 
301
   * @param[in] table message::Table message describing new schema
 
302
   */
 
303
  void createTable(Session *in_session, const message::Table &table);
 
304
  /**
 
305
   * Creates a DropTable Statement GPB message and adds it
 
306
   * to the Session's active Transaction GPB message for pushing
 
307
   * out to the replicator streams.
 
308
   *
 
309
   * @param[in] in_session Pointer to the Session which issued the statement
 
310
   * @param[in] schema_name The schema of the table being dropped
 
311
   * @param[in] table_name The table name of the table being dropped
 
312
   * @param[in] if_exists Did the user specify an IF EXISTS clause?
 
313
   */
 
314
  void dropTable(Session *in_session,
 
315
                     const std::string &schema_name,
 
316
                     const std::string &table_name,
 
317
                     bool if_exists);
 
318
  /**
 
319
   * Creates a TruncateTable Statement GPB message and adds it
 
320
   * to the Session's active Transaction GPB message for pushing
 
321
   * out to the replicator streams.
 
322
   *
 
323
   * @param[in] in_session Pointer to the Session which issued the statement
 
324
   * @param[in] in_table The Table being truncated
 
325
   */
 
326
  void truncateTable(Session *in_session, Table *in_table);
 
327
  /**
 
328
   * Creates a new RawSql GPB message and pushes it to 
 
329
   * replicators.
 
330
   *
 
331
   * @TODO With a real data dictionary, this really shouldn't
 
332
   * be needed.  CREATE TABLE would map to insertRecord call
 
333
   * on the I_S, etc.  Not sure what to do with administrative
 
334
   * commands like CHECK TABLE, though..
 
335
   *
 
336
   * @param in_session Pointer to the Session which issued the statement
 
337
   * @param query Query string
 
338
   */
 
339
  void rawStatement(Session *in_session, const std::string &query);
63
340
  /* transactions: interface to plugin::StorageEngine functions */
64
 
  int ha_commit_one_phase(Session *session, bool all);
65
 
  int ha_rollback_trans(Session *session, bool all);
 
341
  int commitPhaseOne(Session *session, bool all);
 
342
  int rollbackTransaction(Session *session, bool all);
66
343
 
67
344
  /* transactions: these functions never call plugin::StorageEngine functions directly */
68
 
  int ha_commit_trans(Session *session, bool all);
69
 
  int ha_autocommit_or_rollback(Session *session, int error);
 
345
  int commitTransaction(Session *session, bool all);
 
346
  int autocommitOrRollback(Session *session, int error);
70
347
 
71
348
  /* savepoints */
72
 
  int ha_rollback_to_savepoint(Session *session, NamedSavepoint &sv);
73
 
  int ha_savepoint(Session *session, NamedSavepoint &sv);
74
 
  int ha_release_savepoint(Session *session, NamedSavepoint &sv);
75
 
  bool mysql_xa_recover(Session *session);
 
349
  int rollbackToSavepoint(Session *session, NamedSavepoint &sv);
 
350
  int setSavepoint(Session *session, NamedSavepoint &sv);
 
351
  int releaseSavepoint(Session *session, NamedSavepoint &sv);
76
352
 
77
353
  /**
78
354
   * Marks a storage engine as participating in a statement
88
364
   * per statement, and therefore should not need to be idempotent.
89
365
   * Put in assert()s to test this.
90
366
   *
91
 
   * @param[in] Session pointer
92
 
   * @param[in] Descriptor for the resource which will be participating
93
 
   * @param[in] Pointer to the TransactionalStorageEngine resource
 
367
   * @param[in] session Session pointer
 
368
   * @param[in] monitored Descriptor for the resource which will be participating
 
369
   * @param[in] engine Pointer to the TransactionalStorageEngine resource
94
370
   */
95
371
  void registerResourceForStatement(Session *session,
96
372
                                    plugin::MonitoredInTransaction *monitored,
110
386
   * per statement, and therefore should not need to be idempotent.
111
387
   * Put in assert()s to test this.
112
388
   *
113
 
   * @param[in] Session pointer
114
 
   * @param[in] Descriptor for the resource which will be participating
115
 
   * @param[in] Pointer to the TransactionalStorageEngine resource
116
 
   * @param[in] Pointer to the XaResourceManager resource manager
 
389
   * @param[in] session Session pointer
 
390
   * @param[in] monitored Descriptor for the resource which will be participating
 
391
   * @param[in] engine Pointer to the TransactionalStorageEngine resource
 
392
   * @param[in] resource_manager Pointer to the XaResourceManager resource manager
117
393
   */
118
394
  void registerResourceForStatement(Session *session,
119
395
                                    plugin::MonitoredInTransaction *monitored,
151
427
                                      plugin::MonitoredInTransaction *monitored,
152
428
                                      plugin::TransactionalStorageEngine *engine,
153
429
                                      plugin::XaResourceManager *resource_manager);
 
430
 
 
431
  uint64_t getCurrentTransactionId(Session *session);
 
432
 
 
433
  void allocateNewTransactionId();
 
434
 
 
435
  /**************
 
436
   * Events API
 
437
   **************/
 
438
 
 
439
  /**
 
440
   * Send server startup event.
 
441
   *
 
442
   * @param session Session pointer
 
443
   *
 
444
   * @retval true Success
 
445
   * @retval false Failure
 
446
   */
 
447
  bool sendStartupEvent(Session *session);
 
448
 
 
449
  /**
 
450
   * Send server shutdown event.
 
451
   *
 
452
   * @param session Session pointer
 
453
   *
 
454
   * @retval true Success
 
455
   * @retval false Failure
 
456
   */
 
457
  bool sendShutdownEvent(Session *session);
 
458
 
 
459
private:
 
460
 
 
461
  /**
 
462
   * Checks if a field has been updated 
 
463
   *
 
464
   * @param current_field Pointer to the field to check if it is updated 
 
465
   * @in_table Pointer to the Table containing update information
 
466
   * @param old_record Pointer to the raw bytes representing the old record/row
 
467
   * @param new_record Pointer to the raw bytes representing the new record/row
 
468
   */
 
469
  bool isFieldUpdated(Field *current_field,
 
470
                      Table *in_table,
 
471
                      const unsigned char *old_record,
 
472
                      const unsigned char *new_record);
 
473
 
 
474
  /**
 
475
   * Create a Transaction that contains event information and send it off.
 
476
   *
 
477
   * This differs from other uses of Transaction in that we don't use the
 
478
   * message associated with Session. We create a totally new message and
 
479
   * use it.
 
480
   *
 
481
   * @param session Session pointer
 
482
   * @param event Event message to send
 
483
   *
 
484
   * @note Used by the public Events API.
 
485
   *
 
486
   * @returns Non-zero on error
 
487
   */
 
488
  int sendEvent(Session *session, const message::Event &event);
 
489
 
 
490
  /**
 
491
   * Helper method which checks the UpdateHeader to determine 
 
492
   * if it needs to be finalized.  
 
493
   *
 
494
   * @param[in] statement Statement message container to check 
 
495
   * @param[in] in_table Pointer to the Table being updated
 
496
   * @param[in] old_record Pointer to the old data in the record
 
497
   * @param[in] new_record Pointer to the new data in the record
 
498
   */
 
499
  bool useExistingUpdateHeader(message::Statement &statement,
 
500
                               Table *in_table,
 
501
                               const unsigned char *old_record,
 
502
                               const unsigned char *new_record);
 
503
 
 
504
  plugin::XaStorageEngine *xa_storage_engine;
154
505
};
155
506
 
156
507
} /* namespace drizzled */