~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/handler/ha_innodb.cc

Completes the work of removing the weirdness around transaction
boundaries in the storage engine API.

* Transactional storage engines are now all explicitly notified
  of the start of a new "normal" transaction in the new PSE API
  method plugin::TransactionalStorageEngine::doStartTransaction()
  This new method takes a start_transaction_option_t as one of its
  parameters, and passing this option allows the storage engine
  API to cleanly signal the start of a consistent snapshot (and in
  the future additional transaction attributes).  This meant the
  removal of the old start_consistent_snapshot() method.

* The TransactionServices component now fully manages the transaction
  boundaries, notification of transaction boundaries to participating
  resource managers (transactional storage engines)

Adds a simple test case (to be expanded with future XA work) for
transaction behaviour.

Show diffs side-by-side

added added

removed removed

Lines of Context:
270
270
    addAlias("INNOBASE");
271
271
  }
272
272
private:
 
273
  virtual int doStartTransaction(Session *session, start_transaction_option_t options);
273
274
  virtual void doStartStatement(Session *session);
274
275
  virtual void doEndStatement(Session *session);
275
276
public:
348
349
                        the database name: for example, in 'mysql/data/test'
349
350
                        the database name is 'test' */
350
351
 
351
 
  /*********************************************************************
352
 
  Creates an InnoDB transaction struct for the session if it does not yet have one.
353
 
  Starts a new InnoDB transaction if a transaction is not yet started. And
354
 
  assigns a new snapshot for a consistent read if the transaction does not yet
355
 
  have one. */
356
 
  virtual
357
 
  int
358
 
  doStartConsistentSnapshot(
359
 
  /*====================================*/
360
 
                        /* out: 0 */
361
 
        Session*        session);       /* in: MySQL thread handle of the user for whom
362
 
                        the transaction should be committed */
363
352
  /********************************************************************
364
353
  Flushes InnoDB logs to disk and makes a checkpoint. Really, a commit flushes
365
354
  the logs, and the name of this function should be innobase_checkpoint. */
1506
1495
        update_session(session);
1507
1496
}
1508
1497
 
1509
 
/*********************************************************************//**
1510
 
Registers an InnoDB transaction in MySQL, so that the MySQL XA code knows
1511
 
to call the InnoDB prepare and commit, or rollback for the transaction. This
1512
 
MUST be called for every transaction for which the user may call commit or
1513
 
rollback. Calling this several times to register the same transaction is
1514
 
allowed, too.
1515
 
This function also registers the current SQL statement. */
1516
 
static inline
1517
 
void
1518
 
innobase_register_trx_and_stmt(
1519
 
/*===========================*/
1520
 
        plugin::TransactionalStorageEngine *engine, /*!< in: Innobase StorageEngine */
1521
 
        Session*        session)        /*!< in: MySQL thd (connection) object */
1522
 
{
1523
 
        if (session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
1524
 
                /* No autocommit mode, register for a transaction */
1525
 
    TransactionServices &transaction_services= TransactionServices::singleton();
1526
 
    transaction_services.trans_register_ha(session, engine);
1527
 
        }
1528
 
}
1529
 
 
1530
1498
/*****************************************************************//**
1531
1499
Convert an SQL identifier to the MySQL system_charset_info (UTF-8)
1532
1500
and quote it if needed.
2089
2057
have one.
2090
2058
@return 0 */
2091
2059
int
2092
 
InnobaseEngine::doStartConsistentSnapshot(
 
2060
InnobaseEngine::doStartTransaction(
2093
2061
/*====================================*/
2094
 
        Session*        session)        /*!< in: MySQL thread handle of the user for whom
2095
 
                        the transaction should be committed */
 
2062
        Session*        session,        /*!< in: MySQL thread handle of the user for whom
 
2063
                                                 the transaction should be committed */
 
2064
  start_transaction_option_t options)
2096
2065
{
2097
 
        trx_t*  trx;
2098
 
 
2099
2066
        assert(this == innodb_engine_ptr);
2100
2067
 
2101
2068
        /* Create a new trx struct for session, if it does not yet have one */
2102
 
 
2103
 
        trx = check_trx_exists(session);
 
2069
        trx_t *trx = check_trx_exists(session);
2104
2070
 
2105
2071
        /* This is just to play safe: release a possible FIFO ticket and
2106
2072
        search latch. Since we will reserve the kernel mutex, we have to
2107
2073
        release the search system latch first to obey the latching order. */
2108
 
 
2109
2074
        innobase_release_stat_resources(trx);
2110
2075
 
2111
2076
        /* If the transaction is not started yet, start it */
2112
 
 
2113
2077
        trx_start_if_not_started(trx);
2114
2078
 
2115
2079
        /* Assign a read view if the transaction does not have it yet */
2116
 
 
2117
 
        trx_assign_read_view(trx);
2118
 
 
2119
 
        /* Set the MySQL flag to mark that there is an active transaction */
2120
 
 
 
2080
  if (options == START_TRANS_OPT_WITH_CONS_SNAPSHOT)
 
2081
          trx_assign_read_view(trx);
 
2082
 
 
2083
        /* Set the Drizzle flag to mark that there is an active transaction */
2121
2084
        if (trx->active_trans == 0) {
2122
 
                innobase_register_trx_and_stmt(this, current_session);
2123
 
                trx->active_trans = 1;
 
2085
                trx->active_trans= 1;
2124
2086
        }
2125
2087
 
2126
 
        return(0);
 
2088
        return 0;
2127
2089
}
2128
2090
 
2129
2091
/*****************************************************************//**
2153
2115
 
2154
2116
        /* The flag trx->active_trans is set to 1 in
2155
2117
 
2156
 
        1. ::external_lock(),
2157
 
        4. InnobaseEngine::setSavepoint(),
2158
 
        6. InnobaseEngine::doStartConsistentSnapshot(),
 
2118
        1. ::external_lock()
 
2119
  2  InnobaseEngine::doStartStatement()
 
2120
        3. InnobaseEngine::setSavepoint()
 
2121
        4. InnobaseEngine::doStartTransaction()
2159
2122
 
2160
2123
        and it is only set to 0 in a commit or a rollback. If it is 0 we know
2161
2124
        there cannot be resources to be freed and we could return immediately.
8031
7994
   * @todo this should go away
8032
7995
   */
8033
7996
  if (trx->active_trans == 0) {
8034
 
    innobase_register_trx_and_stmt(innodb_engine_ptr, session);
8035
7997
    trx->active_trans= 1;
8036
7998
  }
8037
7999
}
8053
8015
    if (trx->active_trans != 0)
8054
8016
    {
8055
8017
      commit(session, TRUE);
 
8018
      trx->active_trans= 0;
8056
8019
    }
8057
8020
  }
8058
8021
  else
8065
8028
      read_view_close_for_mysql(trx);
8066
8029
    }
8067
8030
  }
8068
 
 
8069
 
  trx->active_trans= 0;
8070
8031
}
8071
8032
 
8072
8033
/*******************************************************************//**