文章目录

  • 一、概念
  • 1.1、事务
  • 1.2、手动提交:autocommit=0
  • 1.3、自动提交:autocommit=1
  • 二、设置 autocommit 的开启和关闭:
  • 2.1、查看当前自动提交状态:
  • 2.2、临时设置方法:
  • 2.3、永久设置方法:
  • 三、spring 底层对自动提交的设置


一、概念

1.1、事务

事务 就是一组的SQL语句,或者说一个独立的工作单元,这一组的SQL语句,要么全部执行成功,要么全部执行失败。
开启事务 : start transaction 或者 begin 提交事务: commit 事务回滚:rollback

1.2、手动提交:autocommit=0

从用户执行 start transaction (开启事务),到用户执行 commit 命令,这个期间,用户的一系列操作为一个完整的事务周期。

如果不执行 commit 命令,系统则默认事务回滚。

1.3、自动提交:autocommit=1

如果用户在当前情况下(autocommit=1)下执行 start transaction 命令,对数据库进行操作,系统则默认用户对数据库的每一个操作为一个孤立的事务,也就是说用户每进行一次操作系都会 即时提交 或者 即时回滚

这种情况下用户的每一个操作都是一个完整的事务周期。

二、设置 autocommit 的开启和关闭:

用户可以将自动提交功能强制置为 OFF 。

这样用户执行SQL语句后将不会被提交了,而执行 commit 命令才提交,执行 rollback 命令回滚。

2.1、查看当前自动提交状态:

mysql> show variables like 'autocommit';
±--------------±------+
| Variable_name | Value |
±--------------±------+
|  autocommit   |  ON   |
±--------------±------+

mysql> show global variables like 'autocommit';  ## 全局的
±--------------±------+
| Variable_name | Value |
±--------------±------+
|   autocommit  |  ON   |
±--------------±------+

2.2、临时设置方法:

将自动提交功能置为ON ,

set autocommit=1;

将自动提交功能置为OFF ,

set autocommit=0;

2.3、永久设置方法:

通过修改配置文件 my.cnf 文件,通过vim编辑my.cnf文件,在[mysqld](服务器选项下)添加:

autocommit=0

三、spring 底层对自动提交的设置

1)mysql 的 autocommit 配置默认是开启的,也就是每执行一条sql都会提交一次,就算显示的开启事务也会导致多条SQL不在一个事务中,
如果需要相关的SQL在同一个事务中执行,那么必须将 autocommit设置为OFF,再显式开启事务。

2)如果使用spring的事务,那么不存在这个问题,spring的事务默认是关闭自动提交的,做法是判断连接池是否开启事务自动提交,如果连接池开启自动提交则设置自动提交为关闭,否则不做操作,因为某些jdbc驱动做设置自动提交关闭代价昂贵。

org.springframework.jdbc.datasource.DataSourceTransactionManager

/**
 * This implementation sets the isolation level but ignores the timeout.
 */
@Override
protected void doBegin(Object transaction, TransactionDefinition definition) {
    //.........
        // 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);
        }
    //.............................
}

spring会将底层连接的自动提交设置为 false。

大部分 java 项目中都会使用到 Spring, 所以即使我们没有对mysql 自动提交做修改,Spring 依然可以保证事务的原子性。