1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 Sun Microsystems
5
* Copyright (c) 2010 Jay Pipes <jaypipes@gmail.com>
7
* This program is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation; version 2 of the License.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22
* @file Transaction processing code
25
#ifndef DRIZZLED_TRANSACTION_SERVICES_H
26
#define DRIZZLED_TRANSACTION_SERVICES_H
28
#include "drizzled/message/transaction.pb.h"
33
/* some forward declarations needed */
36
class MonitoredInTransaction;
37
class XaResourceManager;
38
class TransactionalStorageEngine;
45
* This is a class which manages the XA transaction processing
48
class TransactionServices
51
static const size_t DEFAULT_RECORD_SIZE= 100;
55
TransactionServices() {}
59
* Returns the singleton instance of TransactionServices
61
static inline TransactionServices &singleton()
63
static TransactionServices transaction_services;
64
return transaction_services;
67
* Method which returns the active Transaction message
68
* for the supplied Session. If one is not found, a new Transaction
69
* message is allocated, initialized, and returned.
71
* @param The session processing the transaction
73
message::Transaction *getActiveTransactionMessage(Session *in_session);
75
* Method which attaches a transaction context
76
* the supplied transaction based on the supplied Session's
77
* transaction information. This method also ensure the
78
* transaction message is attached properly to the Session object
80
* @param The transaction message to initialize
81
* @param The Session processing this transaction
83
void initTransactionMessage(message::Transaction &in_transaction, Session *in_session);
85
* Helper method which finalizes data members for the
86
* supplied transaction's context.
88
* @param The transaction message to finalize
89
* @param The Session processing this transaction
91
void finalizeTransactionMessage(message::Transaction &in_transaction, Session *in_session);
93
* Helper method which deletes transaction memory and
94
* unsets Session's transaction and statement messages.
96
void cleanupTransactionMessage(message::Transaction *in_transaction,
99
* Helper method which initializes a Statement message
101
* @param The statement to initialize
102
* @param The type of the statement
103
* @param The session processing this statement
105
void initStatementMessage(message::Statement &statement,
106
message::Statement::Type in_type,
107
Session *in_session);
109
* Finalizes a Statement message and sets the Session's statement
112
* @param The statement to initialize
113
* @param The session processing this statement
115
void finalizeStatementMessage(message::Statement &statement,
116
Session *in_session);
117
/** Helper method which returns an initialized Statement message for methods
118
* doing insertion of data.
120
* @param[in] Pointer to the Session doing the processing
121
* @param[in] Pointer to the Table object being inserted into
123
message::Statement &getInsertStatement(Session *in_session,
127
* Helper method which initializes the header message for
130
* @param[inout] Statement message container to modify
131
* @param[in] Pointer to the Session doing the processing
132
* @param[in] Pointer to the Table being inserted into
134
void setInsertHeader(message::Statement &statement,
138
* Helper method which returns an initialized Statement
139
* message for methods doing updates of data.
141
* @param[in] Pointer to the Session doing the processing
142
* @param[in] Pointer to the Table object being updated
143
* @param[in] Pointer to the old data in the record
144
* @param[in] Pointer to the new data in the record
146
message::Statement &getUpdateStatement(Session *in_session,
148
const unsigned char *old_record,
149
const unsigned char *new_record);
151
* Helper method which initializes the header message for
154
* @param[inout] Statement message container to modify
155
* @param[in] Pointer to the Session doing the processing
156
* @param[in] Pointer to the Table being updated
157
* @param[in] Pointer to the old data in the record
158
* @param[in] Pointer to the new data in the record
160
void setUpdateHeader(message::Statement &statement,
163
const unsigned char *old_record,
164
const unsigned char *new_record);
166
* Helper method which returns an initialized Statement
167
* message for methods doing deletion of data.
169
* @param[in] Pointer to the Session doing the processing
170
* @param[in] Pointer to the Table object being deleted from
172
message::Statement &getDeleteStatement(Session *in_session,
176
* Helper method which initializes the header message for
179
* @param[inout] Statement message container to modify
180
* @param[in] Pointer to the Session doing the processing
181
* @param[in] Pointer to the Table being deleted from
183
void setDeleteHeader(message::Statement &statement,
187
* Commits a normal transaction (see above) and pushes the transaction
188
* message out to the replicators.
190
* @param Pointer to the Session committing the transaction
192
void commitTransactionMessage(Session *in_session);
194
* Marks the current active transaction message as being rolled back and
195
* pushes the transaction message out to replicators.
197
* @param Pointer to the Session committing the transaction
199
void rollbackTransactionMessage(Session *in_session);
201
* Creates a new InsertRecord GPB message and pushes it to
204
* @param Pointer to the Session which has inserted a record
205
* @param Pointer to the Table containing insert information
207
* Grr, returning "true" here on error because of the cursor
208
* reversed bool return crap...fix that.
210
bool insertRecord(Session *in_session, Table *in_table);
212
* Creates a new UpdateRecord GPB message and pushes it to
215
* @param Pointer to the Session which has updated a record
216
* @param Pointer to the Table containing update information
217
* @param Pointer to the raw bytes representing the old record/row
218
* @param Pointer to the raw bytes representing the new record/row
220
void updateRecord(Session *in_session,
222
const unsigned char *old_record,
223
const unsigned char *new_record);
225
* Creates a new DeleteRecord GPB message and pushes it to
228
* @param Pointer to the Session which has deleted a record
229
* @param Pointer to the Table containing delete information
231
void deleteRecord(Session *in_session, Table *in_table);
233
* Creates a CreateSchema Statement GPB message and adds it
234
* to the Session's active Transaction GPB message for pushing
235
* out to the replicator streams.
237
* @param[in] Pointer to the Session which issued the statement
238
* @param[in] message::Schema message describing new schema
240
void createSchema(Session *in_session, const message::Schema &schema);
242
* Creates a DropSchema Statement GPB message and adds it
243
* to the Session's active Transaction GPB message for pushing
244
* out to the replicator streams.
246
* @param[in] Pointer to the Session which issued the statement
247
* @param[in] message::Schema message describing new schema
249
void dropSchema(Session *in_session, const std::string &schema_name);
251
* Creates a CreateTable Statement GPB message and adds it
252
* to the Session's active Transaction GPB message for pushing
253
* out to the replicator streams.
255
* @param[in] Pointer to the Session which issued the statement
256
* @param[in] message::Table message describing new schema
258
void createTable(Session *in_session, const message::Table &table);
260
* Creates a DropTable Statement GPB message and adds it
261
* to the Session's active Transaction GPB message for pushing
262
* out to the replicator streams.
264
* @param[in] Pointer to the Session which issued the statement
265
* @param[in] The schema of the table being dropped
266
* @param[in] The table name of the table being dropped
267
* @param[in] Did the user specify an IF EXISTS clause?
269
void dropTable(Session *in_session,
270
const std::string &schema_name,
271
const std::string &table_name,
274
* Creates a TruncateTable Statement GPB message and adds it
275
* to the Session's active Transaction GPB message for pushing
276
* out to the replicator streams.
278
* @param[in] Pointer to the Session which issued the statement
279
* @param[in] The Table being truncated
281
void truncateTable(Session *in_session, Table *in_table);
283
* Creates a new RawSql GPB message and pushes it to
286
* @TODO With a real data dictionary, this really shouldn't
287
* be needed. CREATE TABLE would map to insertRecord call
288
* on the I_S, etc. Not sure what to do with administrative
289
* commands like CHECK TABLE, though..
291
* @param Pointer to the Session which issued the statement
292
* @param Query string
294
void rawStatement(Session *in_session, const std::string &query);
295
/* transactions: interface to plugin::StorageEngine functions */
296
int ha_commit_one_phase(Session *session, bool all);
297
int ha_rollback_trans(Session *session, bool all);
299
/* transactions: these functions never call plugin::StorageEngine functions directly */
300
int ha_commit_trans(Session *session, bool all);
301
int ha_autocommit_or_rollback(Session *session, int error);
304
int ha_rollback_to_savepoint(Session *session, NamedSavepoint &sv);
305
int ha_savepoint(Session *session, NamedSavepoint &sv);
306
int ha_release_savepoint(Session *session, NamedSavepoint &sv);
307
bool mysql_xa_recover(Session *session);
310
* Marks a storage engine as participating in a statement
315
* This method is idempotent
319
* This method should not be called more than once per resource
320
* per statement, and therefore should not need to be idempotent.
321
* Put in assert()s to test this.
323
* @param[in] Session pointer
324
* @param[in] Descriptor for the resource which will be participating
325
* @param[in] Pointer to the TransactionalStorageEngine resource
327
void registerResourceForStatement(Session *session,
328
plugin::MonitoredInTransaction *monitored,
329
plugin::TransactionalStorageEngine *engine);
332
* Marks an XA storage engine as participating in a statement
337
* This method is idempotent
341
* This method should not be called more than once per resource
342
* per statement, and therefore should not need to be idempotent.
343
* Put in assert()s to test this.
345
* @param[in] Session pointer
346
* @param[in] Descriptor for the resource which will be participating
347
* @param[in] Pointer to the TransactionalStorageEngine resource
348
* @param[in] Pointer to the XaResourceManager resource manager
350
void registerResourceForStatement(Session *session,
351
plugin::MonitoredInTransaction *monitored,
352
plugin::TransactionalStorageEngine *engine,
353
plugin::XaResourceManager *resource_manager);
356
* Registers a resource manager in the "normal" transaction.
360
* This method is idempotent and must be idempotent
361
* because it can be called both by the above
362
* TransactionServices::registerResourceForStatement(),
363
* which occurs at the beginning of each SQL statement,
364
* and also manually when a BEGIN WORK/START TRANSACTION
365
* statement is executed. If the latter case (BEGIN WORK)
366
* is called, then subsequent contained statement transactions
367
* will call this method as well.
371
* This method checks to see if the supplied resource
372
* is also registered in the statement transaction, and
373
* if not, registers the resource in the statement
374
* transaction. This happens ONLY when the user has
375
* called BEGIN WORK/START TRANSACTION, which is the only
376
* time when this method is called except from the
377
* TransactionServices::registerResourceForStatement method.
379
void registerResourceForTransaction(Session *session,
380
plugin::MonitoredInTransaction *monitored,
381
plugin::TransactionalStorageEngine *engine);
382
void registerResourceForTransaction(Session *session,
383
plugin::MonitoredInTransaction *monitored,
384
plugin::TransactionalStorageEngine *engine,
385
plugin::XaResourceManager *resource_manager);
388
} /* namespace drizzled */
390
#endif /* DRIZZLED_TRANSACTION_SERVICES_H */