
# 事务
- 【规格】在GTM-FREE模式下，不允许执行跨节点事务。 在GTM-FREE模式下，如果所执行的SQL语句包含跨节点事务，会报错：Unsupport DML two phase commit under gtm free mode.
  在这种情况下，如果某一条语句必须临时开启跨节点事务，需要在事务中先执行如下命令开启跨节点事务：
  ```
  SET enable_twophase_commit = on;
  ```
  并在事务结束前执行如下命令：
  ```
  RESET enable_twophase_commit;
  ```
  或者：
  ```
  SET enable_twophase_commit = off;
  ```
  
- 【规格】大对象操作不支持事务。 大对象操作包括：创建删除DATABASE、ANALYZE和VACUUM。
  
- 【规则】通过JDBC客户端接入时，关闭autocommit参数，显式的执行事务的COMMIT。
  - 一方面，开启autocommit参数，会导致部分参数（如fetchsize）失效。
  
  - 另一方面，业务应明确业务逻辑，减少对数据库的依赖。
   
- 【规则】通过JDBC接入数据库时，避免拼接多条SQL为一条语句发送执行。 当多条语句拼接为一条语句，且其中包含对象操作时，如果中间对象操作失败，会重新开启新事务执行后续语句。
  示例：
  - 不符合规则语句
    ```
    Connection conn = ....
    try {
        Statement stmt = null;
        try {
            stmt = conn.createStatement();
            stmt.executeUpdate("CREATE TABLE t1 (a int); DROP TABLE t1");
        } finally {
            stmt.close();
        }
        conn.commit();
    } catch(Exception e) {
       conn.rollback();
    } finally {
       conn.close();
    }
    ```
    上述执行语句，如果
    ```
    CREATE TABLE t1;
    ```
    创建失败，会重新开启新事务执行
    ```
    DROP TABLE t1;
    ```
    导致执行失败。
    
  
  - 建议分成两条语句分别发送：
    ```
    Connection conn = ....
    try {
        Statement stmt = null;
        try {
            stmt = conn.createStatement();
            stmt.executeUpdate("CREATE TABLE t1 (a int)");
            stmt.executeUpdate("DROP TABLE t1");
        } finally {
            stmt.close();
        }
        conn.commit();
    } catch(Exception e) {
       conn.rollback();
    } finally {
       conn.close();
    }
    ```
    
    
 
