mysql 默認是開啓 auto commit 的。能夠經過以下命令查看 session 級別和 global 級別的設置:
mysql> select @@session.autocommit;
+----------------------+
| @@session.autocommit |
+----------------------+
| 1 |
+----------------------+
1 row in set (0.00 sec)
mysql> select @@global.autocommit;
+---------------------+
| @@global.autocommit |
+---------------------+
| 1 |
+---------------------+
1 row in set (0.00 sec)
mysql>
那麼若是咱們不想讓 mysql 執行自動提交時,應該如何禁用 autocommit 呢?能夠經過 Cmd-Line、Option file、System Var 上均可用的 init_connect 來設置。
A string to be executed by the server for each client that connects. The string consists of one or more SQL statements. To specify multiple statements, separate them by semicolon characters.
上面這段話的意思是,每一個 client 鏈接上來時都會由 server 執行一次由 init_connect 指定的 sql 字串。(是否能夠認爲是基於 session 的?)
利用這個變量,能夠經過以下方式禁用 autocommit:
方法一:
mysql>SET GLOBAL init_connect='SET autocommit=0';
方法二:
在 MySQL 的配置文件中設置
[mysqld]
init_connect='SET autocommit=0'
方法三:
啓動 mysql 時帶上命令行參數 –init_connect='SET autocommit=0'
值得說明的一點是,這個參數的設置對擁有 super 權限的用戶是無效的,具體緣由說明以下:
Note that the content of init_connect is not executed for users that have the SUPER privilege. This is done so that an erroneous value for init_connect does not prevent all clients from connecting. For example, the value might contain a statement that has a syntax error, thus causing client connections to fail. Not executing init_connect for users that have the SUPER privilege enables them to open a connection and fix the init_connect value.
默認開啓的 autocommit 確定會對 mysql 的性能有必定影響,但既然默認開啓一定是有緣由的,因此若是你不知道本身到底會遇到什麼問題的狀況下仍是不要改這個設置爲妙。舉個例子來講明開啓 autocommit 會產生的性能影響,若是你插入了 1000 條數據,mysql 會 commit 1000 次,若是咱們把 autocommit 關閉掉,經過程序來控制,只要一次commit 就能夠了。
========= 我是分割線
=========
另一篇博客《Innodb表類型中autocommit的設置》中展現了設置 autocommit 爲 0 的效果。
a.
初始狀態+設置 session 級別的 autocommit 爲 0
mysql>
mysql> show binlog events;
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
| mysql-bin.000001 | 4 | Format_desc | 1 | 120 | Server ver: 5.6.10-log, Binlog ver: 4 |
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
1 row in set (0.00 sec)
mysql>
mysql> show tables;
Empty set (0.00 sec)
mysql>
mysql> select @@global.autocommit;
+---------------------+
| @@global.autocommit |
+---------------------+
| 1 |
+---------------------+
1 row in set (0.00 sec)
mysql> select @@session.autocommit;
+----------------------+
| @@session.autocommit |
+----------------------+
| 1 |
+----------------------+
1 row in set (0.00 sec)
mysql>
mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)
mysql>
mysql> select @@global.autocommit;
+---------------------+
| @@global.autocommit |
+---------------------+
| 1 |
+---------------------+
1 row in set (0.00 sec)
mysql> select @@session.autocommit;
+----------------------+
| @@session.autocommit |
+----------------------+
| 0 |
+----------------------+
1 row in set (0.00 sec)
mysql>
b.
建立一個測試表
mysql> create table t_autocommit(
-> id int not null auto_increment,
-> amount int not null default '0',
-> primary key(id)
-> )engine=innodb;
Query OK, 0 rows affected (0.01 sec)
mysql>
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| t_autocommit |
+----------------+
1 row in set (0.00 sec)
mysql>
mysql> describe t_autocommit;
+--------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| amount | int(11) | NO | | 0 | |
+--------+---------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
mysql>
mysql> select * from t_autocommit;
Empty set (0.00 sec)
mysql>
c.
插入數據
mysql>
mysql> insert into t_autocommit set amount=1;
Query OK, 1 row affected (0.00 sec)
mysql>
mysql> select * from t_autocommit;
+----+--------+
| id | amount |
+----+--------+
| 1 | 1 |
+----+--------+
1 row in set (0.00 sec)
mysql>
mysql> update t_autocommit set amount=amount+10;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql>
mysql> select * from t_autocommit;
+----+--------+
| id | amount |
+----+--------+
| 1 | 11 |
+----+--------+
1 row in set (0.00 sec)
mysql>
mysql> show binlog events;
+------------------+-----+-------------+-----------+-------------+----------------------------------------------------------------------------------------------------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+-----+-------------+-----------+-------------+----------------------------------------------------------------------------------------------------------------------------------------+
| mysql-bin.000001 | 4 | Format_desc | 1 | 120 | Server ver: 5.6.10-log, Binlog ver: 4 |
| mysql-bin.000001 | 120 | Query | 1 | 316 | use `test`; create table t_autocommit(
id int not null auto_increment,
amount int not null default '0',
primary key(id)
)engine=innodb |
+------------------+-----+-------------+-----------+-------------+----------------------------------------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)
mysql>
發現 binlog 中僅記錄了 create table 動做,insert 和 update 因爲 autocommit 爲 0 的緣故沒有被記錄到 binlog 中。
d.斷開 mysql ,再從新鏈接。
mysql>
mysql> quit
Bye
[root@Betty ~]#
[root@Betty ~]# mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.6.10-log Source distribution
Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
mysql> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql>
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| t_autocommit |
+----------------+
1 row in set (0.00 sec)
mysql>
mysql> select * from t_autocommit;
Empty set (0.00 sec)
mysql>
發現什麼數據都沒有。爲何呢?由於 SQL 語句並無被本身(當前 session)提交給 server 端去處理,只是在當前鏈接中作了相應處理。
重複上面的實驗,可是保持 autocommit 的默認值(1)。
mysql>
mysql> show binlog events;
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
| mysql-bin.000001 | 4 | Format_desc | 1 | 120 | Server ver: 5.6.10-log, Binlog ver: 4 |
+------------------+-----+-------------+-----------+-------------+---------------------------------------+
1 row in set (0.00 sec)
mysql>
mysql> show tables;
Empty set (0.01 sec)
mysql>
mysql> select @@global.autocommit;
+---------------------+
| @@global.autocommit |
+---------------------+
| 1 |
+---------------------+
1 row in set (0.00 sec)
mysql>
mysql> select @@session.autocommit;
+----------------------+
| @@session.autocommit |
+----------------------+
| 1 |
+----------------------+
1 row in set (0.00 sec)
mysql>
mysql> create table t_autocommit(
-> id int not null auto_increment,
-> amount int not null default '0',
-> primary key(id)
-> )engine=innodb;
Query OK, 0 rows affected (0.01 sec)
mysql>
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| t_autocommit |
+----------------+
1 row in set (0.00 sec)
mysql>
mysql> describe t_autocommit;
+--------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| amount | int(11) | NO | | 0 | |
+--------+---------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
mysql>
mysql> insert into t_autocommit set amount=1;
Query OK, 1 row affected (0.00 sec)
mysql>
mysql> select * from t_autocommit;
+----+--------+
| id | amount |
+----+--------+
| 1 | 1 |
+----+--------+
1 row in set (0.00 sec)
mysql>
mysql> update t_autocommit set amount=amount+10;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql>
mysql> select * from t_autocommit;
+----+--------+
| id | amount |
+----+--------+
| 1 | 11 |
+----+--------+
1 row in set (0.00 sec)
mysql>
mysql> show binlog events;
+------------------+-----+-------------+-----------+-------------+----------------------------------------------------------------------------------------------------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+-----+-------------+-----------+-------------+----------------------------------------------------------------------------------------------------------------------------------------+
| mysql-bin.000001 | 4 | Format_desc | 1 | 120 | Server ver: 5.6.10-log, Binlog ver: 4 |
| mysql-bin.000001 | 120 | Query | 1 | 316 | use `test`; create table t_autocommit(
id int not null auto_increment,
amount int not null default '0',
primary key(id)
)engine=innodb |
| mysql-bin.000001 | 316 | Query | 1 | 395 | BEGIN |
| mysql-bin.000001 | 395 | Intvar | 1 | 427 | INSERT_ID=1 |
| mysql-bin.000001 | 427 | Query | 1 | 538 | use `test`; insert into t_autocommit set amount=1 |
| mysql-bin.000001 | 538 | Xid | 1 | 569 | COMMIT /* xid=62 */ |
| mysql-bin.000001 | 569 | Query | 1 | 648 | BEGIN |
| mysql-bin.000001 | 648 | Query | 1 | 762 | use `test`; update t_autocommit set amount=amount+10 |
| mysql-bin.000001 | 762 | Xid | 1 | 793 | COMMIT /* xid=64 */ |
+------------------+-----+-------------+-----------+-------------+----------------------------------------------------------------------------------------------------------------------------------------+
9 rows in set (0.00 sec)
mysql>
mysql> quit
Bye
[root@Betty ~]#
[root@Betty ~]# mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.6.10-log Source distribution
Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
mysql> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql>
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| t_autocommit |
+----------------+
1 row in set (0.00 sec)
mysql>
mysql> select * from t_autocommit;
+----+--------+
| id | amount |
+----+--------+
| 1 | 11 |
+----+--------+
1 row in set (0.00 sec)
mysql>
mysql>
這回該有的都有了。
========= 我是分割線
=========
網友說法:
不要設定 autocommit 這個開關,讓它保持 autocommit=1 這個默認狀態。 日常有查詢\更新都是須要獲得最新的數據,根本不須要啓動一個事務,除非有特定情況才須要開啓事務,再手工用 start transaction ... commit /rollback 。
這種全局設置,在生產環境中沒有多大意義。通常都是在應用程序框架(如鏈接池的庫)中設置 autocommit 是否爲 ON/OFF, 說白了,就是獲得數據庫鏈接之後,顯示的調用一次 set autocommit on/off (or =1/0)