专注Java教育14年 全国咨询/投诉热线:400-8080-105
动力节点LOGO图
始于2009,口口相传的Java黄埔军校
首页 hot资讯 浅谈MySQL自动提交模式

浅谈MySQL自动提交模式

更新时间:2021-01-25 17:10:55 来源:动力节点 浏览1051次

默认情况下, MySQL启用自动提交模式(变量autocommit为ON)。这意味着, 只要你执行DML操作的语句,MySQL会立即隐式提交事务(Implicit Commit)。如果你了解SQL Server数据库的话,你会发现MySQL自动提交模式跟SQL Server有很多相似之处。

 

1 .MySQL的autocommit设置

MySQL默认是开启自动提交的,即每一条DML(增删改)语句都会被作为一个单独的事务进行隐式提交。如果修改为关闭状态,则执行DML语句之后要手动提交 才能生效。
查询当前会话的自动提交是否开启:

mysql> show variables like 'autocommit';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| autocommit    | ON    |

+---------------+-------+

查询全局的自动提交是否开启:

mysql> show global variables like 'autocommit';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| autocommit    | ON    |

+---------------+-------+

通过修改autocommit变量可以关闭和开启操作

关闭当前会话的自动提交模式

mysql> set autocommit=0;

 

 

mysql> show variables like 'autocommit';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| autocommit    | OFF   |

+---------------+-------+

 

 全局的autocommit还是开启状态

mysql> show global variables like 'autocommit';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| autocommit    | ON    |

+---------------+-------+

 

 

 关闭全局的autocommit

mysql> set global autocommit=0;

 

 

mysql> show global variables like 'autocommit';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| autocommit    | OFF   |

+---------------+-------+

如果想要MySQL服务重启之后仍能生效,需要设置系统环境变量。MySQL5.7 在cnf配置文件中[mysqld]下面设置autocommit的值。

[mysqld]

...

autocommit=0

 

 

2.修改autocommit模式

mysql> set session autocommit=0;

Query OK, 0 rows affected (0.00 sec)

 

mysql> show session variables like 'autocommit';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| autocommit    | OFF   |

+---------------+-------+

1 row in set (0.00 sec)

 

mysql> show global variables like 'autocommit';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| autocommit    | ON    |

+---------------+-------+

1 row in set (0.00 sec)

 

mysql>

 

mysql> set global autocommit=0;

Query OK, 0 rows affected (0.00 sec)

 

mysql> show global variables like 'autocommit';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| autocommit    | OFF   |

+---------------+-------+

1 row in set (0.01 sec)

 

mysql> 注意,上述SQL修改会话系统变量或全局系统变量,只对当前实例有效,如果MySQL服务重启的话,这些设置就会丢失,如果要永久生效,就必须在配置文件中修改系统变量。[mysqld]

autocommit=0不过网上还有种方式,如下所示,在MySQL 5.6/5.7下测试,发现不生效,查了一下,这种方式似乎从MySQL 5.6开始已经不生效了,必须用autocommit=0这种方式替换。[mysqld]

init_connect='SET autocommit=0'

 

3.Spring中MySQL对自动提交的控制

MySQL的JDBC驱动包 mysql-connector-java 会给会话的connection默认开启自动提交,譬如 mysql-connector-java-8.0.22版本的代码:

//com.mysql.cj.protocol.a.NativeServerSession.java

    private boolean autoCommit = true;

常用的数据库连接池 如HikariCP,druid等,默认也是开启自动提交,会将connection的自动提交设置都改为true。
druid在初始化DataSource的时候设置connection的autocommit为true。代码如下:

com.alibaba.druid.pool.DruidAbstractDataSource.java

    protected volatile boolean                         defaultAutoCommit                         = true;

    ...

    public void initPhysicalConnection(Connection conn, Map<String, Object> variables, Map<String, Object> globalVariables) throws SQLException {

        if (conn.getAutoCommit() != defaultAutoCommit) {

           //将connection的autocommit设置为true

            conn.setAutoCommit(defaultAutoCommit);

        }

        ...

 

    }

HikariCP 初始化DataSource的默认配置 中autocommit也是true:

com.zaxxer.hikari.HikariConfig.java

   public HikariConfig()

   {

      ...

      isAutoCommit = true;

   }

对于事务管理器PlatformTransactionManager管理的显式事务(譬如@Transactional注解声明)在 开启事务时会关闭自动提交模式。

代码如下:

@Override

protected void doBegin(Object transaction, TransactionDefinition definition) {

DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;

Connection con = null;

 

try {

             ........

 

// Switch to manual commit if necessary. This is very expensive in some JDBC drivers,

// so we don't want to do it unnecessarily (for example if we've explicitly

// configured the connection pool to set it already).

if (con.getAutoCommit()) {

txObject.setMustRestoreAutoCommit(true);

if (logger.isDebugEnabled()) {

logger.debug("Switching JDBC Connection [" + con + "] to manual commit");

}

                                //关闭自动提交模

                                con.setAutoCommit(false);

}

 

            .......

}

 

catch (Throwable ex) {

          .......

}

}

 

MySQL的autocommit模式默认是打开状态,为了防止手动的DML操作导致失误,生产环境可以设置为默认关闭的状态。一般的JDBC连接池默认都是开启状态,而且是可配置的。显式事务下会设置成关闭状态,单纯的修改数据库环境的autocommit不会对代码的行为产生影响。因此,MySQL的自动提交模式还是很值得信赖的,自动提交模式可以通过服务器变量AUTOCOMMIT来控制,且不会对显式事务造成影响。在本站的MySQL教程中,有着对MySQL自动提交模式的详细讲解,还没有弄通透的小伙伴可以前去观看学习哦。

 

 

提交申请后,顾问老师会电话与您沟通安排学习

免费课程推荐 >>
技术文档推荐 >>