# 事务
GaussDB数据库兼容MySQL的事务，但存在部分差异。本章节介绍GaussDB的M-Compatibility数据库中事务相关的差异。
#### 事务默认隔离级别
M-Compatibility默认隔离级别为READ COMMITTED，MySQL默认隔离级别为REPEATABLE READ。
```
-- 查看当前事务隔离级别。
m_db=# SHOW transaction_isolation;
```
#### 子事务
M-Compatibility中，通过SAVEPOINT用于在当前事务里建立一个新的保存点（子事务），使用ROLLBACK TO SAVEPOINT回滚到一个保存点（子事务），子事务回滚后父事务可以继续运行，子事务的回滚不影响父事务的事务状态。
MySQL不存在创建保存点（子事务）。
#### 嵌套事务
嵌套事务指在事务块中开启新事务。
M-Compatibility中，正常事务块中开启新事务会警告存在一个进行中的事务，忽略开启命令；异常事务块中开启新事务将报错，必须在执行ROLLBACK/COMMIT之后才可以执行，执行ROLLBACK/COMMIT会回滚之前语句。
MySQL中，正常事务块中开启新事务会先把之前事务提交，然后开启新事务；异常事务块中开启新事务会忽略错误，提交之前无错误的语句并开启新事务。
```
-- M-Compatibility正常事务块中，开启新事务会警告并忽略。
m_db=# DROP TABLE IF EXISTS test_t;
m_db=# CREATE TABLE test_t(a int, b int);
m_db=# BEGIN;
m_db=# INSERT INTO test_t values(1, 2);
m_db=# BEGIN;   -- 会警告there is already a transaction in progress。
m_db=# SELECT * FROM test_t ORDER BY 1;
m_db=# COMMIT; 
-- M-Compatibility异常事务块中，开启新事务会报错，必须ROLLBACK/COMMIT之后才可以执行。
m_db=# BEGIN;
m_db=# ERROR sql; -- 错误语句。
m_db=# BEGIN; -- 报错。
m_db=# COMMIT; -- ROLLBACK/COMMIT之后才可以执行。
```
#### 隐式提交的语句
M-Compatibility使用GaussDB存储，继承GaussDB事务机制，事务中执行DDL、DCL不会自动提交。
MySQL在DDL、DCL、管理类语句，锁相关语句会自动提交。
```
-- M-Compatibility创建表和设置GUC参数可以回滚掉。
m_db=# DROP TABLE IF EXISTS test_table_rollback;
m_db=# BEGIN;
m_db=# CREATE TABLE test_table_rollback(a int, b int);
m_db=# \d test_table_rollback;
m_db=# ROLLBACK;
m_db=# \d test_table_rollback; -- 不存在该表。
```
#### SET TRANSACTION差异
M-Compatibility中，SET TRANSACTION同时设置多次隔离级别/事务访问模式时，只有最后一个会生效；多个事务特性支持使用空格和逗号分隔。
MySQL中SET TRANSACTION不允许设置多次隔离级别/事务访问模式；多个事务特性只支持使用逗号分隔。
表1SET TRANSACTION差异 
| 语法                       | 功能                               | 差异                                                                                                                      |
|:---|:---|:---|
| SET TRANSACTION          | 设置事务特性。                            | M-Compatibility中，SET TRANSACTION在会话级别生效；MySQL中SET TRANSACTION在下一个事务生效。                                                    |
| SET SESSION TRANSACTION | 设置会话级事务特性。                       | -                                                                                                                        |
| SET GLOBAL TRANSACTION  | 设置全局会话级事务特性，该特性适用于后续会话，对当前会话无影响。 | M-Compatibility中，GLOBAL是全局会话级别生效，只针对当前数据库实例，其它数据库不影响。 MySQL中，会使所有数据库生效。 |
   
```
-- SET TRANSACTION会话级生效。
m_db=# SET TRANSACTION ISOLATION LEVEL READ COMMITTED READ WRITE;
m_db=# SHOW transaction_isolation;
m_db=# SHOW transaction_read_only;
-- M-Compatibility同时设置多次隔离级别/事务访问模式，最后一个生效。
m_db=# SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED, ISOLATION LEVEL REPEATABLE READ, READ WRITE, READ ONLY;
m_db=# SHOW transaction_isolation; -- repeatable read
m_db=# SHOW transaction_read_only; -- on
```
#### START TRANSACTION差异
M-Compatibility中，START TRANSACTION开启事务时，同时支持设置隔离级别；同时设置多次隔离级别/事务访问模式时，只有最后一个会生效；当前版本不支持立即开启一致性快照；多个事务特性支持空格和逗号分隔。
MySQL的start transaction 开启事务时，不支持设置隔离级别，不支持设置多次事务访问模式；多个事务特性只支持逗号分隔。
```
-- 开启事务设置隔离级别。
m_db=# START TRANSACTION ISOLATION LEVEL READ COMMITTED;
m_db=# COMMIT;
-- 多次设置访问模式。
m_db=# START TRANSACTION READ ONLY, READ WRITE;
m_db=# COMMIT;
```
#### 事务相关的GUC参数
表2事务相关的GUC参数差异 
| GUC参数                            | 功能                                                                                                | 差异                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
|:---|:---|:---|
| autocommit                   | 设置事务自动提交模式。                                                                                        | -                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| transaction_isolation         | 在M-Compatibility中是设置当前事务的隔离级别。 在MySQL中是设置会话级事务的隔离级别。   | - GaussDB中，通过使用SET transaction_isolation = value命令，只能改变当前事务的隔离级别。如果想要改变会话级的隔离级别，可以使用default_transaction_isolation。在MySQL中，通过使用SET命令，可以改变会话级的事务隔离级别。  - 支持范围差异。 MySQL中，支持以下隔离级别设置，对大小写不敏感，对空格敏感： - READ COMMITTED  - READ UNCOMMITTED  - REPEATABLE READ  - SERIALIZABLE   GaussDB中，支持以下隔离级别设置，对大小写和空格敏感： - read committed  - read uncommitted（可以设置，但实际生效的隔离级别为read committed）  - repeatable read  - serializable（可以设置，但实际生效的隔离级别为repeatable read）  - default（设置和会话中默认隔离级别一样）  - 设置m_format_dev_version = 's2'时，支持MySQL的隔离级别设置。     - 在GaussDB中，新事务的transaction_isolation值将被初始化为default_transaction_isolation的值。   |
| tx_isolation                  | 设置事务的隔离级别； tx_isolation和transaction_isolation是同义词。 | M-Compatibility中不支持查询，不支持修改。需要时，建议查询transaction_isolation。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| default_transaction_isolation | 设置事务的隔离级别。                                                                                          | M-Compatibility中通过SET设置会改变会话级事务隔离级别。 MySQL中不支持该系统参数。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| transaction_read_only          | 设置事务的访问模式。                                                                                      | - 在M-Compatibility中，通过使用SET命令，只能改变当前事务的访问模式。如果想要改变会话级的访问模式，可以使用default_transaction_read_only。 在MySQL中，通过使用SET命令，可以改变会话级的事务隔离级别。   - 在GaussDB中，新事务的transaction_read_only值将被初始化为default_transaction_read_only的值。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| tx_read_only                  | 设置事务的访问模式。tx_read_only和transaction_read_only是同义词。                                                | M-Compatibility中不支持查询，不支持修改。需要时，建议查询transaction_read_only。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| default_transaction_read_only | 设置事务的访问模式。                                                                                       | M-Compatibility中通过SET设置会改变会话级事务访问模式；MySQL中不支持该系统参数。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
   
