mysql的autocommit詳解


autocommit的測試

對於innodb表:

首先創建兩個innodb表:
mysql> create table tab_kx(a int auto_increment,primary key(a));
Query OK, 0 rows affected (0.16 sec)

mysql> create table tab_kx2(a int auto_increment,primary key(a));
Query OK, 0 rows affected (0.17 sec)

在session1,設置autocommit為OFF:
mysql> set autocommit=0;                  
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like '%autocommit%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | OFF   |
+---------------+-------+
1 row in set (0.00 sec)

在session2設置autocommit為ON:
mysql> show variables like '%autocommit%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | ON    |
+---------------+-------+
1 row in set (0.00 sec)


在session1,對tab_kx插入三行數據但不提交:
mysql> insert into tab_kx values('');
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> insert into tab_kx values('');
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> insert into tab_kx values('');
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> select * from tab_kx;
+---+
| a |
+---+
| 1 |
| 2 |
| 3 |
+---+
3 rows in set (0.00 sec)

mysql> select * from tab_kx2;
Empty set (0.00 sec)

此時查看session2是否可以看到這三行數據:
mysql> select * from tab_kx;
Empty set (0.00 sec)

【說明】,session2看不到其他session沒有提交的DML;
此時在session2插入四行數據到表tab_kx2(由於是auto commit的,所以不需要提交):
mysql> insert into tab_kx2 values();
Query OK, 1 row affected (0.07 sec)

mysql> insert into tab_kx2 values();
Query OK, 1 row affected (0.04 sec)

mysql> insert into tab_kx2 values();
Query OK, 1 row affected (0.04 sec)

mysql> insert into tab_kx2 values();
Query OK, 1 row affected (0.02 sec)

mysql> select * from tab_kx2;                                    
+---+
| a |
+---+
| 1 |
| 2 |
| 3 |
| 4 |
+---+
4 rows in set (0.00 sec)

【注意】但此時session1仍然看不到tab_kx2的數據,
mysql> select * from tab_kx2;
Empty set (0.00 sec)
當手動執行commit時,才可以看到這些數據,同時session2也可以看到tab_kx表的數據。
mysql> commit;
Query OK, 0 rows affected (0.03 sec)

mysql> select * from tab_kx2;
+---+
| a |
+---+
| 1 |
| 2 |
| 3 |
| 4 |
+---+
4 rows in set (0.00 sec)


【結論】對於autocommit為OFF的session,其事務開始時間點之后發生的DML操作對其都是不可見的,只有當事務結束時才可見。(其他session的DDL即時可見)
另外,如果其session執行了一個DDL,會隱式提交之前的事務,DML的修改其他session可見了。
但有意思的是,當我一個session中對tab_kx表drop的時候,會話被阻塞了(如果隱式提交了,應該不會發生這種情況),在另個session中執行讀,也被阻塞了
此時我在原來的session(autocommit為OFF)執行顯示提交commit:
其他session都被“激活”了,而且是按執行順序激活的。


myisam表:

創建兩個myisam表,
mysql> create table tab_kx(a int auto_increment,primary key (a)) engine=myisam; 
Query OK, 0 rows affected (0.05 sec)

mysql> create table tab_kx2(a int auto_increment,primary key (a)) engine=myisam;
Query OK, 0 rows affected (0.05 sec)

在session1,(autocommit為OFF)插入三行數據,
mysql> insert into tab_kx values();
Query OK, 1 row affected (0.00 sec)

mysql> insert into tab_kx values();
Query OK, 1 row affected (0.00 sec)

mysql> insert into tab_kx values();
Query OK, 1 row affected (0.00 sec)

mysql> select * from tab_kx;
+---+
| a |
+---+
| 1 |
| 2 |
| 3 |
+---+
3 rows in set (0.00 sec)


在其他session中查詢tab_kx,
mysql> select * from tab_kx;
+---+
| a |
+---+
| 1 |
| 2 |
| 3 |
+---+
3 rows in set (0.00 sec)

可以看到結果,這與innodb的表不同;不需要顯示提交,DML修改就可以對外可見了。
【結論】myisam是非事務的存儲引擎,commit是對事物有效的,所以沒啥作用。
【注意】但當我對tab_kx做刪除時,會話被阻塞,盡管沒有事務性,但autocommit=OFF仍然在起作用,雖然不再持有表鎖;
在session1執行顯示提交commit,立刻解鎖,阻塞的會話被激活。

注:mysql官方文檔如是說:

     ALTER TABLE運行時會對原表進行臨時復制,在副本上進行更改,然后刪除原表,再對新表進行重命名。在執行ALTER TABLE時,其它用戶可以閱讀原表,但是對表的更新和修改的操作將被延遲,直到新表生成為止。新表生成后,這些更新和修改信息會自動轉移到新表上。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM