### 27.12.7 性能模式事务表

[27.12.7.1 事件\_交易\_当前表](performance-schema-events-transactions-current-table.html)
[27.12.7.2 事件\_交易\_历史表](performance-schema-events-transactions-history-table.html)
[27.12.7.3 事件\_交易\_历史\_长桌](performance-schema-events-transactions-history-long-table.html)

性能模式检测交易。在事件层次结构中，等待事件嵌套在阶段事件中，阶段事件嵌套在语句事件中，而语句事件嵌套在事务事件中。

这些表存储事务事件：

-   [`events_transactions_current`](performance-schema-events-transactions-current-table.html)：每个线程的当前事务事件。

-   [`events_transactions_history`](performance-schema-events-transactions-history-table.html)：每个线程结束的最新事务事件。

-   [`events_transactions_history_long`](performance-schema-events-transactions-history-long-table.html)：已在全球范围内（跨所有线程）结束的最新事务事件。

    以下部分描述了事务事件表。还有汇总表，汇总有关事务事件的信息；看[第 27.12.20.5 节，“事务汇总表”](performance-schema-transaction-summary-tables.html).

    有关三个事务事件表之间关系的更多信息，请参见[第 27.9 节，“当前和历史事件的性能模式表”](performance-schema-event-tables.html).

-   [配置事务事件收集](performance-schema-transaction-tables.html#performance-schema-transaction-tables-configuration)

-   [交易边界](performance-schema-transaction-tables.html#performance-schema-transaction-tables-transaction-boundaries)

-   [交易工具](performance-schema-transaction-tables.html#performance-schema-transaction-tables-instrumentation)

-   [事务和嵌套事件](performance-schema-transaction-tables.html#performance-schema-transaction-tables-nested-events)

-   [事务和存储程序](performance-schema-transaction-tables.html#performance-schema-transaction-tables-stored-programs)

-   [事务和保存点](performance-schema-transaction-tables.html#performance-schema-transaction-tables-savepoints)

-   [事务和错误](performance-schema-transaction-tables.html#performance-schema-transaction-tables-errors)

#### 配置事务事件收集

要控制是否收集交易事件，请设置相关工具和消费者的状态：

-   这[`setup_instruments`](performance-schema-setup-instruments-table.html)表包含一个名为`交易`.使用此工具来启用或禁用单个事务事件类的收集。

-   这[`setup_consumers`](performance-schema-setup-consumers-table.html)表包含名称对应于当前和历史事务事件表名称的消费者值。使用这些消费者来过滤事务事件的集合。

    这`交易`仪器和`events_transactions_current`和`events_transactions_history`默认情况下启用事务消费者：


```
mysql> SELECT NAME, ENABLED, TIMED
       FROM performance_schema.setup_instruments
       WHERE NAME = 'transaction';
+-------------+---------+-------+
| NAME        | ENABLED | TIMED |
+-------------+---------+-------+
| transaction | YES     | YES   |
+-------------+---------+-------+
mysql> SELECT *
       FROM performance_schema.setup_consumers
       WHERE NAME LIKE 'events_transactions%';
+----------------------------------+---------+
| NAME                             | ENABLED |
+----------------------------------+---------+
| events_transactions_current      | YES     |
| events_transactions_history      | YES     |
| events_transactions_history_long | NO      |
+----------------------------------+---------+
```

要在服务器启动时控制事务事件收集，请在您的`我的.cnf`文件：

-   使能够：

    ```
    [mysqld]
    performance-schema-instrument='transaction=ON'
    performance-schema-consumer-events-transactions-current=ON
    performance-schema-consumer-events-transactions-history=ON
    performance-schema-consumer-events-transactions-history-long=ON
    ```

-   禁用：

    ```
    [mysqld]
    performance-schema-instrument='transaction=OFF'
    performance-schema-consumer-events-transactions-current=OFF
    performance-schema-consumer-events-transactions-history=OFF
    performance-schema-consumer-events-transactions-history-long=OFF
    ```

    要在运行时控制事务事件收集，请更新[`setup_instruments`](performance-schema-setup-instruments-table.html)和[`setup_consumers`](performance-schema-setup-consumers-table.html)表：

-   使能够：

    ```
    UPDATE performance_schema.setup_instruments
    SET ENABLED = 'YES', TIMED = 'YES'
    WHERE NAME = 'transaction';

    UPDATE performance_schema.setup_consumers
    SET ENABLED = 'YES'
    WHERE NAME LIKE 'events_transactions%';
    ```

-   禁用：

    ```
    UPDATE performance_schema.setup_instruments
    SET ENABLED = 'NO', TIMED = 'NO'
    WHERE NAME = 'transaction';

    UPDATE performance_schema.setup_consumers
    SET ENABLED = 'NO'
    WHERE NAME LIKE 'events_transactions%';
    ```

    要仅收集特定事务事件表的事务事件，请启用`交易`工具，但只有与所需表相对应的事务消费者。

    有关配置事件收集的更多信息，请参阅[第 27.3 节，“性能模式启动配置”](performance-schema-startup-configuration.html)， 和[第 27.4 节，“性能模式运行时配置”](performance-schema-runtime-configuration.html).

#### 交易边界

在 MySQL 服务器中，事务以这些语句显式开始：

```
START TRANSACTION | BEGIN | XA START | XA BEGIN
```

事务也隐式开始。例如，当[`自动提交`](server-system-variables.html#sysvar_autocommit)启用系统变量后，每条语句的开始都会启动一个新事务。

什么时候[`自动提交`](server-system-variables.html#sysvar_autocommit)被禁用时，提交事务之后的第一条语句标志着新事务的开始。在提交之前，后续语句是事务的一部分。

事务以这些语句显式结束：

```
COMMIT | ROLLBACK | XA COMMIT | XA ROLLBACK
```

通过执行 DDL 语句、锁定语句和服务器管理语句，事务也会隐式结束。

在下面的讨论中，参考[`开始交易`](commit.html)也适用于[`开始`](commit.html),[`XA 开始`](xa-statements.html)， 和[`XA 开始`](xa-statements.html).同样，参考[`犯罪`](commit.html)和[`回滚`](commit.html)适用于[`XA 提交`](xa-statements.html)和[`XA 回滚`](xa-statements.html)， 分别。

Performance Schema 定义了与服务器类似的事务边界。事务事件的开始和结束与服务器中相应的状态转换紧密匹配：

-   对于显式启动的事务，事务事件在处理[`开始交易`](commit.html)陈述。

-   对于隐式启动的事务，事务事件从前一个事务结束后使用事务引擎的第一条语句开始。

-   对于任何事务，无论是显式结束还是隐式结束，当服务器在处理[`犯罪`](commit.html)要么[`回滚`](commit.html).

    这种方法有一些微妙的含义：

-   Performance Schema 中的事务事件不完全包括与相应的语句事件相关的语句事件[`开始交易`](commit.html),[`犯罪`](commit.html)， 要么[`回滚`](commit.html)陈述。事务事件和这些语句之间有少量的时间重叠。

-   使用非事务引擎的语句对连接的事务状态没有影响。对于隐式事务，事务事件从使用事务引擎的第一条语句开始。这意味着仅在非事务表上运行的语句将被忽略，即使遵循[`开始交易`](commit.html).

    为了说明，请考虑以下场景：


```
1. SET autocommit = OFF;
2. CREATE TABLE t1 (a INT) ENGINE = InnoDB;
3. START TRANSACTION;                       -- Transaction 1 START
4. INSERT INTO t1 VALUES (1), (2), (3);
5. CREATE TABLE t2 (a INT) ENGINE = MyISAM; -- Transaction 1 COMMIT
                                            -- (implicit; DDL forces commit)
6. INSERT INTO t2 VALUES (1), (2), (3);     -- Update nontransactional table
7. UPDATE t2 SET a = a + 1;                 -- ... and again
8. INSERT INTO t1 VALUES (4), (5), (6);     -- Write to transactional table
                                            -- Transaction 2 START (implicit)
9. COMMIT;                                  -- Transaction 2 COMMIT
```

从服务器的角度来看，Transaction 1 在 table 时结束`t2`被建造。事务 2 在访问事务表之前不会启动，尽管对非事务表进行了干预更新。

从性能模式的角度来看，事务 2 在服务器转换为活动事务状态时启动。语句 6 和 7 不包含在 Transaction 2 的边界内，这与服务器将事务写入二进制日志的方式是一致的。

#### 交易工具

三个属性定义事务：

-   访问模式（只读、读写）

-   隔离级别（[`可序列化`](innodb-transaction-isolation-levels.html#isolevel_serializable),[`可重复阅读`](innodb-transaction-isolation-levels.html#isolevel_repeatable-read), 等等)

-   隐式 ([`自动提交`](server-system-variables.html#sysvar_autocommit)启用）或显式（[`自动提交`](server-system-variables.html#sysvar_autocommit)禁用）

    为了降低事务检测的复杂性并确保收集的事务数据提供完整、有意义的结果，所有事务都独立于访问模式、隔离级别或自动提交模式进行检测。

    要选择性地检查事务历史记录，请使用事务事件表中的属性列：`访问模式`,`ISOLATION_LEVEL`， 和`自动提交`.

    可以通过多种方式降低事务检测的成本，例如根据用户、帐户、主机或线程（客户端连接）启用或禁用事务检测。

#### 事务和嵌套事件

事务事件的父事件是发起事务的事件。对于显式启动的事务，这包括[`开始交易`](commit.html)和[`承诺与链`](commit.html)陈述。对于隐式启动的事务，它是前一个事务结束后使用事务引擎的第一条语句。

通常，事务是事务期间启动的所有事件的顶级父级，包括显式结束事务的语句，例如[`犯罪`](commit.html)和[`回滚`](commit.html).异常是隐式结束事务的语句，例如 DDL 语句，在这种情况下，必须在执行新语句之前提交当前事务。

#### 事务和存储程序

事务和存储的程序事件相关如下：

-   存储过程

    存储过程独立于事务运行。存储过程可以在事务中启动，事务可以在存储过程中启动或结束。如果从事务中调用，存储过程可以执行强制提交父事务然后启动新事务的语句。

    如果存储过程在事务中启动，则该事务是存储过程事件的父级。

    如果事务由存储过程启动，则存储过程是事务事件的父级。

-   存储函数

    存储函数被限制导致显式或隐式提交或回滚。存储的函数事件可以驻留在父事务事件中。

-   触发器

    触发器作为访问与其关联的表的语句的一部分而激活，因此触发器事件的父级始终是激活它的语句。

    触发器不能发出导致事务显式或隐式提交或回滚的语句。

-   预定活动

    计划事件主体中语句的执行发生在新连接中。在父事务中嵌套计划事件不适用。

#### 事务和保存点

Savepoint 语句被记录为单独的语句事件。事务事件包括单独的计数器[`保存点`](savepoint.html),[`回滚到保存点`](savepoint.html)， 和[`释放保存点`](savepoint.html)交易期间发表的声明。

#### 事务和错误

事务中发生的错误和警告记录在语句事件中，但不记录在相应的事务事件中。这包括特定于事务的错误和警告，例如非事务表上的回滚或 GTID 一致性错误。
