略微加速

略速 - 互联网笔记

MySQL自动提交

2021-02-20 leiting (2909阅读)

标签 MySql

在MySQL中,如果不更改其自动提交变量,则系统会自动向数据库提交结果,用户在执行数据库操作过程中,不需要使用START TRANSACTION语句开始事务,应用COMMIT或者ROLLBACK提交事务或执行回滚操作。如果用户希望通过控制MySQL自动提交参数,可以更改提交模式,这一更改过程是通过设置AUTOCOMMIT变量来实现的。

1、开启自动提交功能

SET AUTOCOMMIT = 1;

MySQL中默认情况下的自动提交功能是已经开启的。

2、关闭自动提交功能。

SET AUTOCOMMIT = 0;

关闭自动提交功能后,只用当执行COMMIT命令后,MySQL才将数据表中的资料提交到数据库中。如果执行ROLLBACK命令,数据将会被回滚。如果不提交事务,而终止MySQL会话,数据库将会自动执行回滚操作。


MySQL的autocommit(自动提交)默认是开启,其对mysql的性能有一定影响,举个例子来说,如果你插入了1000条数据,mysql会commit1000次的,如果我们把autocommit关闭掉,通过程序来控制,只要一次commit就可以了。

1,我们可以通过set来设置autocommit

2,我们可以修改mysql的配置文件my.cnf来关闭autocommit

init_connect='SET autocommit=0'  #在mysqld里面加上这些内容

 #有一点要注意,连接mysql用户的权限不能大于启动mysql的用户的权限,不然init_connect='SET autocommit=0'根本不会启作用,也不会报任何错误。

 


==============================================

MySQL的自动提交模式

 

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

 

 

 

查看autocommit模式

 

 

由于变量autocommit分会话系统变量与全局系统变量,所以查询的时候,最好区别是会话系统变量还是全局系统变量。

 

 

mysql> show session variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | ON    |
+---------------+-------+
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>

 

 

 

Value的值为ON,表示autocommit开启。OFF表示autocommit关闭。

 

 

 

修改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'


 

 

 

 

autocommit与显性事务的关系

 

 

对于显性事务start transaction或begin, 在自动提交模式关闭(关闭隐式提交)的情况下,开启一个事务上下文。首先数据库会隐式提交之前的还未被提交的操作,同时开启一个新事务。如有不明,可以用下面小实验理解一下:

 

测试如下所示:

 

mysql> select connection_id();
+-----------------+
| connection_id() |
+-----------------+
|               1 |
+-----------------+
1 row in set (0.00 sec)
mysql> show variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | ON    |
+---------------+-------+
1 row in set (0.00 sec)
 
mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)
mysql> delete from MyDB.test where name='kerry';
Query OK, 1 row affected (0.00 sec)

 

 

此时在会话2中查看,此时可以查询到会话ID为1的事务信息, 如下所示

 

mysql>  select connection_id();
+-----------------+
| connection_id() |
+-----------------+
|               2 |
+-----------------+
1 row in set (0.00 sec)
 
mysql> SELECT a.trx_state,
    ->        b.event_name,
    ->        a.trx_started,
    ->        b.timer_wait / 1000000000000 timer_wait,
    ->        a.trx_mysql_thread_id        blocking_trx_id,
    ->        b.sql_text
    -> FROM   information_schema.innodb_trx a,
    ->        performance_schema.events_statements_current b,
    ->        performance_schema.threads c
    -> WHERE  a.trx_mysql_thread_id = c.processlist_id
    ->        AND b.thread_id = c.thread_id;
+-----------+----------------------+---------------------+------------+-----------------+------------------------------------------+
| trx_state | event_name           | trx_started         | timer_wait | blocking_trx_id | sql_text                                 |
+-----------+----------------------+---------------------+------------+-----------------+------------------------------------------+
| RUNNING   | statement/sql/delete | 2018-03-23 14:55:00 |     0.0010 |               1 | delete from MyDB.test where name='kerry' |
+-----------+----------------------+---------------------+------------+-----------------+------------------------------------------+
1 row in set (0.00 sec)

 

如果在会话1当中开启显性事务,那么之前挂起的事务会自动提交,然后,你再去会话2当中查询,就发现之前的DELETE操作已经提交。

 

 

 

 

mysql>  select connection_id();
+-----------------+
| connection_id() |
+-----------------+
|               2 |
+-----------------+
1 row in set (0.00 sec)
 
mysql> SELECT a.trx_state,
    ->        b.event_name,
    ->        a.trx_started,
    ->        b.timer_wait / 1000000000000 timer_wait,
    ->        a.trx_mysql_thread_id        blocking_trx_id,
    ->        b.sql_text
    -> FROM   information_schema.innodb_trx a,
    ->        performance_schema.events_statements_current b,
    ->        performance_schema.threads c
    -> WHERE  a.trx_mysql_thread_id = c.processlist_id
    ->        AND b.thread_id = c.thread_id;
+-----------+----------------------+---------------------+------------+-----------------+------------------------------------------+
| trx_state | event_name           | trx_started         | timer_wait | blocking_trx_id | sql_text                                 |
+-----------+----------------------+---------------------+------------+-----------------+------------------------------------------+
| RUNNING   | statement/sql/delete | 2018-03-23 14:55:00 |     0.0010 |               1 | delete from MyDB.test where name='kerry' |
+-----------+----------------------+---------------------+------------+-----------------+------------------------------------------+
1 row in set (0.00 sec)
 
mysql> SELECT a.trx_state,
    ->        b.event_name,
    ->        a.trx_started,
    ->        b.timer_wait / 1000000000000 timer_wait,
    ->        a.trx_mysql_thread_id        blocking_trx_id,
    ->        b.sql_text
    -> FROM   information_schema.innodb_trx a,
    ->        performance_schema.events_statements_current b,
    ->        performance_schema.threads c
    -> WHERE  a.trx_mysql_thread_id = c.processlist_id
    ->        AND b.thread_id = c.thread_id;
Empty set (0.00 sec)

 

 

With START TRANSACTION, autocommit remains disabled until you end the transaction with COMMIT or ROLLBACK. The autocommit mode then reverts to its previous state

使用START TRANSACTION,自动提交将保持禁用状态,直到你使用COMMIT或ROLLBACK结束事务。 自动提交模式然后恢复到之前的状态(如果start transaction 前 autocommit = 1,则完成本次事务后 autocommit 还是 1。如果 start transaction 前 autocommit = 0,则完成本次事务后 autocommit 还是 0)


北京半月雨文化科技有限公司.版权所有 京ICP备12026184号-3