~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

Merge Jay

Show diffs side-by-side

added added

removed removed

Lines of Context:
268
268
    table_definition_ext= plugin::DEFAULT_DEFINITION_FILE_EXT;
269
269
    addAlias("INNOBASE");
270
270
  }
271
 
 
 
271
private:
 
272
  virtual int doStartTransaction(Session *session, start_transaction_option_t options);
 
273
  virtual void doStartStatement(Session *session);
 
274
  virtual void doEndStatement(Session *session);
 
275
public:
272
276
  virtual
273
277
  int
274
278
  close_connection(
344
348
                        the database name: for example, in 'mysql/data/test'
345
349
                        the database name is 'test' */
346
350
 
347
 
  /*********************************************************************
348
 
  Creates an InnoDB transaction struct for the session if it does not yet have one.
349
 
  Starts a new InnoDB transaction if a transaction is not yet started. And
350
 
  assigns a new snapshot for a consistent read if the transaction does not yet
351
 
  have one. */
352
 
  virtual
353
 
  int
354
 
  doStartConsistentSnapshot(
355
 
  /*====================================*/
356
 
                        /* out: 0 */
357
 
        Session*        session);       /* in: MySQL thread handle of the user for whom
358
 
                        the transaction should be committed */
359
351
  /********************************************************************
360
352
  Flushes InnoDB logs to disk and makes a checkpoint. Really, a commit flushes
361
353
  the logs, and the name of this function should be innobase_checkpoint. */
1502
1494
        update_session(session);
1503
1495
}
1504
1496
 
1505
 
/*********************************************************************//**
1506
 
Registers that InnoDB takes part in an SQL statement, so that MySQL knows to
1507
 
roll back the statement if the statement results in an error. This MUST be
1508
 
called for every SQL statement that may be rolled back by MySQL. Calling this
1509
 
several times to register the same statement is allowed, too. */
1510
 
static inline
1511
 
void
1512
 
innobase_register_stmt(
1513
 
/*===================*/
1514
 
        plugin::TransactionalStorageEngine*     engine, /*!< in: Innobase hton */
1515
 
        Session*        session)        /*!< in: MySQL thd (connection) object */
1516
 
{
1517
 
        assert(engine == innodb_engine_ptr);
1518
 
        /* Register the statement */
1519
 
  TransactionServices &transaction_services= TransactionServices::singleton();
1520
 
        transaction_services.trans_register_ha(session, FALSE, engine);
1521
 
}
1522
 
 
1523
 
/*********************************************************************//**
1524
 
Registers an InnoDB transaction in MySQL, so that the MySQL XA code knows
1525
 
to call the InnoDB prepare and commit, or rollback for the transaction. This
1526
 
MUST be called for every transaction for which the user may call commit or
1527
 
rollback. Calling this several times to register the same transaction is
1528
 
allowed, too.
1529
 
This function also registers the current SQL statement. */
1530
 
static inline
1531
 
void
1532
 
innobase_register_trx_and_stmt(
1533
 
/*===========================*/
1534
 
        plugin::TransactionalStorageEngine *engine, /*!< in: Innobase StorageEngine */
1535
 
        Session*        session)        /*!< in: MySQL thd (connection) object */
1536
 
{
1537
 
        /* NOTE that actually innobase_register_stmt() registers also
1538
 
        the transaction in the AUTOCOMMIT=1 mode. */
1539
 
 
1540
 
        innobase_register_stmt(engine, session);
1541
 
 
1542
 
        if (session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
1543
 
 
1544
 
                /* No autocommit mode, register for a transaction */
1545
 
    TransactionServices &transaction_services= TransactionServices::singleton();
1546
 
    transaction_services.trans_register_ha(session, TRUE, engine);
1547
 
        }
1548
 
}
1549
 
 
1550
1497
/*****************************************************************//**
1551
1498
Convert an SQL identifier to the MySQL system_charset_info (UTF-8)
1552
1499
and quote it if needed.
1714
1661
        prebuilt->read_just_key = 0;
1715
1662
}
1716
1663
 
1717
 
/*****************************************************************//**
1718
 
Call this when you have opened a new table handle in HANDLER, before you
1719
 
call index_read_idx() etc. Actually, we can let the cursor stay open even
1720
 
over a transaction commit! Then you should call this before every operation,
1721
 
fetch next etc. This function inits the necessary things even after a
1722
 
transaction commit. */
1723
 
UNIV_INTERN
1724
 
void
1725
 
ha_innobase::init_table_handle_for_HANDLER(void)
1726
 
/*============================================*/
1727
 
{
1728
 
        /* If current session does not yet have a trx struct, create one.
1729
 
        If the current handle does not yet have a prebuilt struct, create
1730
 
        one. Update the trx pointers in the prebuilt struct. Normally
1731
 
        this operation is done in external_lock. */
1732
 
 
1733
 
        update_session(ha_session());
1734
 
 
1735
 
        /* Initialize the prebuilt struct much like it would be inited in
1736
 
        external_lock */
1737
 
 
1738
 
        innobase_release_stat_resources(prebuilt->trx);
1739
 
 
1740
 
        /* If the transaction is not started yet, start it */
1741
 
 
1742
 
        trx_start_if_not_started(prebuilt->trx);
1743
 
 
1744
 
        /* Assign a read view if the transaction does not have it yet */
1745
 
 
1746
 
        trx_assign_read_view(prebuilt->trx);
1747
 
 
1748
 
        /* Set the MySQL flag to mark that there is an active transaction */
1749
 
 
1750
 
        if (prebuilt->trx->active_trans == 0) {
1751
 
 
1752
 
                innobase_register_trx_and_stmt(innodb_engine_ptr, user_session);
1753
 
 
1754
 
                prebuilt->trx->active_trans = 1;
1755
 
        }
1756
 
 
1757
 
        /* We did the necessary inits in this function, no need to repeat them
1758
 
        in row_search_for_mysql */
1759
 
 
1760
 
        prebuilt->sql_stat_start = FALSE;
1761
 
 
1762
 
        /* We let HANDLER always to do the reads as consistent reads, even
1763
 
        if the trx isolation level would have been specified as SERIALIZABLE */
1764
 
 
1765
 
        prebuilt->select_lock_type = LOCK_NONE;
1766
 
        prebuilt->stored_select_lock_type = LOCK_NONE;
1767
 
 
1768
 
        /* Always fetch all columns in the index record */
1769
 
 
1770
 
        prebuilt->hint_need_to_fetch_extra_cols = ROW_RETRIEVE_ALL_COLS;
1771
 
 
1772
 
        /* We want always to fetch all columns in the whole row? Or do
1773
 
        we???? */
1774
 
 
1775
 
        prebuilt->used_in_HANDLER = TRUE;
1776
 
        reset_template(prebuilt);
1777
 
}
1778
 
 
1779
1664
/*********************************************************************//**
1780
1665
Opens an InnoDB database.
1781
1666
@return 0 on success, error code on failure */
2177
2062
have one.
2178
2063
@return 0 */
2179
2064
int
2180
 
InnobaseEngine::doStartConsistentSnapshot(
 
2065
InnobaseEngine::doStartTransaction(
2181
2066
/*====================================*/
2182
 
        Session*        session)        /*!< in: MySQL thread handle of the user for whom
2183
 
                        the transaction should be committed */
 
2067
        Session*        session,        /*!< in: MySQL thread handle of the user for whom
 
2068
                                                 the transaction should be committed */
 
2069
  start_transaction_option_t options)
2184
2070
{
2185
 
        trx_t*  trx;
2186
 
 
2187
2071
        assert(this == innodb_engine_ptr);
2188
2072
 
2189
2073
        /* Create a new trx struct for session, if it does not yet have one */
2190
 
 
2191
 
        trx = check_trx_exists(session);
 
2074
        trx_t *trx = check_trx_exists(session);
2192
2075
 
2193
2076
        /* This is just to play safe: release a possible FIFO ticket and
2194
2077
        search latch. Since we will reserve the kernel mutex, we have to
2195
2078
        release the search system latch first to obey the latching order. */
2196
 
 
2197
2079
        innobase_release_stat_resources(trx);
2198
2080
 
2199
2081
        /* If the transaction is not started yet, start it */
2200
 
 
2201
2082
        trx_start_if_not_started(trx);
2202
2083
 
2203
2084
        /* Assign a read view if the transaction does not have it yet */
2204
 
 
2205
 
        trx_assign_read_view(trx);
2206
 
 
2207
 
        /* Set the MySQL flag to mark that there is an active transaction */
2208
 
 
 
2085
  if (options == START_TRANS_OPT_WITH_CONS_SNAPSHOT)
 
2086
          trx_assign_read_view(trx);
 
2087
 
 
2088
        /* Set the Drizzle flag to mark that there is an active transaction */
2209
2089
        if (trx->active_trans == 0) {
2210
 
                innobase_register_trx_and_stmt(this, current_session);
2211
 
                trx->active_trans = 1;
 
2090
                trx->active_trans= 1;
2212
2091
        }
2213
2092
 
2214
 
        return(0);
 
2093
        return 0;
2215
2094
}
2216
2095
 
2217
2096
/*****************************************************************//**
2241
2120
 
2242
2121
        /* The flag trx->active_trans is set to 1 in
2243
2122
 
2244
 
        1. ::external_lock(),
2245
 
        2. ::start_stmt(),
2246
 
        3. innobase_query_caching_of_table_permitted(),
2247
 
        4. InnobaseEngine::setSavepoint(),
2248
 
        5. ::init_table_handle_for_HANDLER(),
2249
 
        6. InnobaseEngine::start_consistent_snapshot(),
 
2123
        1. ::external_lock()
 
2124
  2  InnobaseEngine::doStartStatement()
 
2125
        3. InnobaseEngine::setSavepoint()
 
2126
        4. InnobaseEngine::doStartTransaction()
2250
2127
 
2251
2128
        and it is only set to 0 in a commit or a rollback. If it is 0 we know
2252
2129
        there cannot be resources to be freed and we could return immediately.
4566
4443
 
4567
4444
  A) if the user has not explicitly set any MySQL table level locks:
4568
4445
 
4569
 
  1) MySQL calls ::external_lock to set an 'intention' table level lock on
4570
 
the table of the handle instance. There we set
4571
 
prebuilt->sql_stat_start = TRUE. The flag sql_stat_start should be set
4572
 
true if we are taking this table handle instance to use in a new SQL
4573
 
statement issued by the user. We also increment trx->n_mysql_tables_in_use.
4574
 
 
4575
 
  2) If prebuilt->sql_stat_start == TRUE we 'pre-compile' the MySQL search
 
4446
  1) Drizzle calls StorageEngine::doStartStatement(), indicating to
 
4447
     InnoDB that a new SQL statement has begun.
 
4448
 
 
4449
  2a) For each InnoDB-managed table in the SELECT, Drizzle calls ::external_lock
 
4450
     to set an 'intention' table level lock on the table of the Cursor instance.
 
4451
     There we set prebuilt->sql_stat_start = TRUE. The flag sql_stat_start should 
 
4452
     be set true if we are taking this table handle instance to use in a new SQL
 
4453
     statement issued by the user.
 
4454
 
 
4455
  2b) If prebuilt->sql_stat_start == TRUE we 'pre-compile' the MySQL search
4576
4456
instructions to prebuilt->template of the table handle instance in
4577
4457
::index_read. The template is used to save CPU time in large joins.
4578
4458
 
4584
4464
  4) We do the SELECT. MySQL may repeatedly call ::index_read for the
4585
4465
same table handle instance, if it is a join.
4586
4466
 
4587
 
  5) When the SELECT ends, MySQL removes its intention table level locks
4588
 
in ::external_lock. When trx->n_mysql_tables_in_use drops to zero,
4589
 
 (a) we execute a COMMIT there if the autocommit is on,
 
4467
5) When the SELECT ends, the Drizzle kernel calls doEndStatement()
 
4468
 
 
4469
 (a) we execute a COMMIT there if the autocommit is on. The Drizzle interpreter 
 
4470
     does NOT execute autocommit for pure read transactions, though it should.
 
4471
     That is why we must execute the COMMIT in ::doEndStatement().
4590
4472
 (b) we also release possible 'SQL statement level resources' InnoDB may
4591
 
have for this SQL statement. The MySQL interpreter does NOT execute
4592
 
autocommit for pure read transactions, though it should. That is why the
4593
 
table Cursor in that case has to execute the COMMIT in ::external_lock.
 
4473
     have for this SQL statement.
 
4474
 
 
4475
  @todo
 
4476
 
 
4477
  Remove need for InnoDB to call autocommit for read-only trx
 
4478
 
 
4479
  @todo Check the below is still valid (I don't think it is...)
4594
4480
 
4595
4481
  B) If the user has explicitly set MySQL table level locks, then MySQL
4596
4482
does NOT call ::external_lock at the start of the statement. To determine
7182
7068
}
7183
7069
 
7184
7070
/******************************************************************//**
7185
 
MySQL calls this function at the start of each SQL statement inside LOCK
7186
 
TABLES. Inside LOCK TABLES the ::external_lock method does not work to
7187
 
mark SQL statement borders. Note also a special case: if a temporary table
7188
 
is created inside LOCK TABLES, MySQL has not called external_lock() at all
7189
 
on that table.
7190
 
MySQL-5.0 also calls this before each statement in an execution of a stored
7191
 
procedure. To make the execution more deterministic for binlogging, MySQL-5.0
7192
 
locks all tables involved in a stored procedure with full explicit table
7193
 
locks (session_in_lock_tables(session) holds in store_lock()) before executing
7194
 
the procedure.
7195
 
@return 0 or error code */
7196
 
UNIV_INTERN
7197
 
int
7198
 
ha_innobase::start_stmt(
7199
 
/*====================*/
7200
 
        Session*        session,        /*!< in: handle to the user thread */
7201
 
        thr_lock_type   lock_type)
7202
 
{
7203
 
        trx_t*          trx;
7204
 
 
7205
 
        update_session(session);
7206
 
 
7207
 
        trx = prebuilt->trx;
7208
 
 
7209
 
        /* Here we release the search latch and the InnoDB thread FIFO ticket
7210
 
        if they were reserved. They should have been released already at the
7211
 
        end of the previous statement, but because inside LOCK TABLES the
7212
 
        lock count method does not work to mark the end of a SELECT statement,
7213
 
        that may not be the case. We MUST release the search latch before an
7214
 
        INSERT, for example. */
7215
 
 
7216
 
        innobase_release_stat_resources(trx);
7217
 
 
7218
 
        /* Reset the AUTOINC statement level counter for multi-row INSERTs. */
7219
 
        trx->n_autoinc_rows = 0;
7220
 
 
7221
 
        prebuilt->sql_stat_start = TRUE;
7222
 
        prebuilt->hint_need_to_fetch_extra_cols = 0;
7223
 
        reset_template(prebuilt);
7224
 
 
7225
 
        if (!prebuilt->mysql_has_locked) {
7226
 
                /* This handle is for a temporary table created inside
7227
 
                this same LOCK TABLES; since MySQL does NOT call external_lock
7228
 
                in this case, we must use x-row locks inside InnoDB to be
7229
 
                prepared for an update of a row */
7230
 
 
7231
 
                prebuilt->select_lock_type = LOCK_X;
7232
 
        } else {
7233
 
                if (trx->isolation_level != TRX_ISO_SERIALIZABLE
7234
 
                        && session_sql_command(session) == SQLCOM_SELECT
7235
 
                        && lock_type == TL_READ) {
7236
 
 
7237
 
                        /* For other than temporary tables, we obtain
7238
 
                        no lock for consistent read (plain SELECT). */
7239
 
 
7240
 
                        prebuilt->select_lock_type = LOCK_NONE;
7241
 
                } else {
7242
 
                        /* Not a consistent read: restore the
7243
 
                        select_lock_type value. The value of
7244
 
                        stored_select_lock_type was decided in:
7245
 
                        1) ::store_lock(),
7246
 
                        2) ::external_lock(),
7247
 
                        3) ::init_table_handle_for_HANDLER(), and
7248
 
                      */
7249
 
 
7250
 
                        prebuilt->select_lock_type =
7251
 
                                prebuilt->stored_select_lock_type;
7252
 
                }
7253
 
        }
7254
 
 
7255
 
        trx->detailed_error[0] = '\0';
7256
 
 
7257
 
        /* Set the MySQL flag to mark that there is an active transaction */
7258
 
        if (trx->active_trans == 0) {
7259
 
 
7260
 
                innobase_register_trx_and_stmt(innodb_engine_ptr, session);
7261
 
                trx->active_trans = 1;
7262
 
        } else {
7263
 
                innobase_register_stmt(innodb_engine_ptr, session);
7264
 
        }
7265
 
 
7266
 
        return(0);
7267
 
}
7268
 
 
7269
 
/******************************************************************//**
7270
7071
Maps a MySQL trx isolation level code to the InnoDB isolation level code
7271
7072
@return InnoDB isolation level */
7272
7073
static inline
7286
7087
 
7287
7088
/******************************************************************//**
7288
7089
As MySQL will execute an external lock for every new table it uses when it
7289
 
starts to process an SQL statement (an exception is when MySQL calls
7290
 
start_stmt for the handle) we can use this function to store the pointer to
7291
 
the Session in the handle. We will also use this function to communicate
7292
 
to InnoDB that a new SQL statement has started and that we must store a
7293
 
savepoint to our transaction handle, so that we are able to roll back
7294
 
the SQL statement in case of an error.
 
7090
starts to process an SQL statement.  We can use this function to store the pointer to
 
7091
the Session in the handle.
7295
7092
@return 0 */
7296
7093
UNIV_INTERN
7297
7094
int
7300
7097
        Session*        session,        /*!< in: handle to the user thread */
7301
7098
        int     lock_type)      /*!< in: lock type */
7302
7099
{
7303
 
        trx_t*          trx;
7304
 
 
7305
 
 
7306
7100
        update_session(session);
7307
7101
 
7308
 
        trx = prebuilt->trx;
 
7102
  trx_t *trx= prebuilt->trx;
7309
7103
 
7310
7104
        prebuilt->sql_stat_start = TRUE;
7311
7105
        prebuilt->hint_need_to_fetch_extra_cols = 0;
7323
7117
        if (lock_type != F_UNLCK) {
7324
7118
                /* MySQL is setting a new table lock */
7325
7119
 
7326
 
                trx->detailed_error[0] = '\0';
7327
 
 
7328
 
                /* Set the MySQL flag to mark that there is an active
7329
 
                transaction */
7330
 
                if (trx->active_trans == 0) {
7331
 
 
7332
 
                        innobase_register_trx_and_stmt(innodb_engine_ptr, session);
7333
 
                        trx->active_trans = 1;
7334
 
                } else if (trx->n_mysql_tables_in_use == 0) {
7335
 
                        innobase_register_stmt(innodb_engine_ptr, session);
7336
 
                }
7337
 
 
7338
7120
                if (trx->isolation_level == TRX_ISO_SERIALIZABLE
7339
7121
                        && prebuilt->select_lock_type == LOCK_NONE
7340
7122
                        && session_test_options(session,
7367
7149
                        trx->mysql_n_tables_locked++;
7368
7150
                }
7369
7151
 
7370
 
                trx->n_mysql_tables_in_use++;
7371
7152
                prebuilt->mysql_has_locked = TRUE;
7372
7153
 
7373
7154
                return(0);
7374
7155
        }
7375
7156
 
7376
7157
        /* MySQL is releasing a table lock */
7377
 
 
7378
 
        trx->n_mysql_tables_in_use--;
7379
7158
        prebuilt->mysql_has_locked = FALSE;
7380
 
 
7381
 
        /* Release a possible FIFO ticket and search latch. Since we
7382
 
        may reserve the kernel mutex, we have to release the search
7383
 
        system latch first to obey the latching order. */
7384
 
 
7385
 
        innobase_release_stat_resources(trx);
7386
 
 
7387
 
        /* If the MySQL lock count drops to zero we know that the current SQL
7388
 
        statement has ended */
7389
 
 
7390
 
        if (trx->n_mysql_tables_in_use == 0) {
7391
 
 
7392
 
                trx->mysql_n_tables_locked = 0;
7393
 
                prebuilt->used_in_HANDLER = FALSE;
7394
 
 
7395
 
                if (!session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
7396
 
                        if (trx->active_trans != 0) {
7397
 
                                getTransactionalEngine()->commit(session, TRUE);
7398
 
                        }
7399
 
                } else {
7400
 
                        if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
7401
 
                                                && trx->global_read_view) {
7402
 
 
7403
 
                                /* At low transaction isolation levels we let
7404
 
                                each consistent read set its own snapshot */
7405
 
 
7406
 
                                read_view_close_for_mysql(trx);
7407
 
                        }
7408
 
                }
7409
 
        }
 
7159
        trx->mysql_n_tables_locked= 0;
7410
7160
 
7411
7161
        return(0);
7412
7162
}
7749
7499
 
7750
7500
        trx = check_trx_exists(session);
7751
7501
 
7752
 
        /* NOTE: MySQL can call this function with lock 'type' TL_IGNORE!
7753
 
        Be careful to ignore TL_IGNORE if we are going to do something with
7754
 
        only 'real' locks! */
7755
 
 
7756
 
        /* If no MySQL table is in use, we need to set the isolation level
7757
 
        of the transaction. */
7758
 
 
7759
 
        if (lock_type != TL_IGNORE
7760
 
            && trx->n_mysql_tables_in_use == 0) {
7761
 
                trx->isolation_level = innobase_map_isolation_level(
7762
 
                        (enum_tx_isolation) session_tx_isolation(session));
7763
 
 
7764
 
                if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
7765
 
                    && trx->global_read_view) {
7766
 
 
7767
 
                        /* At low transaction isolation levels we let
7768
 
                        each consistent read set its own snapshot */
7769
 
 
7770
 
                        read_view_close_for_mysql(trx);
7771
 
                }
7772
 
        }
7773
 
 
7774
7502
        assert(EQ_CURRENT_SESSION(session));
7775
7503
        const uint32_t sql_command = session_sql_command(session);
7776
7504
 
7851
7579
                TABLESPACE or TRUNCATE TABLE then allow multiple
7852
7580
                writers. Note that ALTER TABLE uses a TL_WRITE_ALLOW_READ
7853
7581
                < TL_WRITE_CONCURRENT_INSERT.
7854
 
 
7855
 
                We especially allow multiple writers if MySQL is at the
7856
 
                start of a stored procedure call (SQLCOM_CALL) or a
7857
 
                stored function call (MySQL does have in_lock_tables
7858
 
                TRUE there). */
 
7582
                */
7859
7583
 
7860
7584
                if ((lock_type >= TL_WRITE_CONCURRENT_INSERT
7861
7585
                     && lock_type <= TL_WRITE)
7871
7595
                would conflict with TL_WRITE_ALLOW_WRITE, blocking all inserts
7872
7596
                to t2. Convert the lock to a normal read lock to allow
7873
7597
                concurrent inserts to t2.
7874
 
 
7875
 
                We especially allow concurrent inserts if MySQL is at the
7876
 
                start of a stored procedure call (SQLCOM_CALL)
7877
 
                (MySQL does have session_in_lock_tables() TRUE there). */
 
7598
    */
7878
7599
 
7879
7600
                if (lock_type == TL_READ_NO_INSERT) {
7880
7601
 
8249
7970
 
8250
7971
        return(char_length);
8251
7972
}
 
7973
/**
 
7974
 * We will also use this function to communicate
 
7975
 * to InnoDB that a new SQL statement has started and that we must store a
 
7976
 * savepoint to our transaction handle, so that we are able to roll back
 
7977
 * the SQL statement in case of an error.
 
7978
 */
 
7979
void
 
7980
InnobaseEngine::doStartStatement(
 
7981
        Session *session) /*!< in: handle to the Drizzle session */
 
7982
{
 
7983
  /* 
 
7984
   * Create the InnoDB transaction structure
 
7985
   * for the session
 
7986
   */
 
7987
        trx_t *trx= check_trx_exists(session);
 
7988
 
 
7989
  /* "reset" the error message for the transaction */
 
7990
  trx->detailed_error[0]= '\0';
 
7991
 
 
7992
        /* Set the isolation level of the transaction. */
 
7993
  trx->isolation_level= innobase_map_isolation_level((enum_tx_isolation) session_tx_isolation(session));
 
7994
 
 
7995
  /* 
 
7996
   * Set the Drizzle flag to mark that there is an active
 
7997
   * transaction.
 
7998
   *
 
7999
   * @todo this should go away
 
8000
   */
 
8001
  if (trx->active_trans == 0) {
 
8002
    trx->active_trans= 1;
 
8003
  }
 
8004
}
 
8005
 
 
8006
void
 
8007
InnobaseEngine::doEndStatement(
 
8008
  Session *session)
 
8009
{
 
8010
  trx_t *trx= check_trx_exists(session);
 
8011
 
 
8012
  /* Release a possible FIFO ticket and search latch. Since we
 
8013
  may reserve the kernel mutex, we have to release the search
 
8014
  system latch first to obey the latching order. */
 
8015
 
 
8016
  innobase_release_stat_resources(trx);
 
8017
 
 
8018
  if (! session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
 
8019
  {
 
8020
    if (trx->active_trans != 0)
 
8021
    {
 
8022
      commit(session, TRUE);
 
8023
      trx->active_trans= 0;
 
8024
    }
 
8025
  }
 
8026
  else
 
8027
  {
 
8028
    if (trx->isolation_level <= TRX_ISO_READ_COMMITTED &&
 
8029
        trx->global_read_view)
 
8030
    {
 
8031
      /* At low transaction isolation levels we let
 
8032
      each consistent read set its own snapshot */
 
8033
      read_view_close_for_mysql(trx);
 
8034
    }
 
8035
  }
 
8036
}
8252
8037
 
8253
8038
/*******************************************************************//**
8254
8039
This function is used to prepare an X/Open XA distributed transaction.