1. 程式人生 > >mysql的事務提交(commit)與回滾(rollback)詳解

mysql的事務提交(commit)與回滾(rollback)詳解

1.SQL概念
Structured Query Language- - -結構化查詢語言
有 資料定義語言(DDL),例如:CREATE、DROP、ALTER等語句;
資料操作語言(DML),例如:INSERT(插入)、UPDATE(修改)、DELETE(刪除)語句;
資料查詢語言(DQL),例如:SELECT語句;
資料控制語言(DCL),例如: COMMIT、ROLLBACK、GRANT、REVOKE等語句

2.COMMIT:提交事務
檢視事務狀態:select @@autocommit; show variables like ‘%autocommit%’;
1或者ON表示自動提交;0或者OFF表示手動提交:需要commit命令提交事務。

mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
|            1 |
+--------------+
1 row in set (0.00 sec)

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

設定手動提交:set autocommit=0; set autocommit=OFF;

mysql> set autocommit=0;
Query OK, 0 rows affected (0.02 sec)

mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
|            0 |
+--------------+
1 row in set (0.00 sec)
mysql> set autocommit=OFF;
Query OK, 0 rows affected (0.00 sec)

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

下面實際演示一下:
首先新開session1並建表create table test_a(id1 int,id2 int);

然後設定手動提交set autocommit=0;(這樣設定只對當前session有效,是臨時的,如果想要永久全域性設定,修改my.cnf檔案,新增autocommit=0);

再向表中插入資料insert into test_a values(1,1);

此時新開第二個session2,查詢該表select * from test_a;可以發現,此時在session2上是查詢不到資料的,原因就是因為在session1的事務還未提交。但是此時在session1是可以查到,這是不是和上述有點矛盾呢,其實不然,未提交的資料會臨時寫到記憶體或磁碟(記憶體不足的情況下),且未提交的資料上有個鎖(涉及隔離級別,後續講解),鎖是隻有當前事務唯一持有的,所以其他事務取不到,但當前事務是可以讀取的。 <這段劃重點,可以多理解一下>

接著換一種思路,在session2(自動提交)上插入一條新資料insert into test_a values(2,2);然後去session1查詢,發現session1上仍然查不到新增的資料,這裡有人會問session2不是設定的自動提交嗎,為什麼session1查不到資料呢?這是因為當session為非自動提交狀態時,自事務開始後的DML操作對其都是不可見的,只有事務結束後才可見。在session1執行commit,就可以查詢到新增資料了。

再看第三種情況,在session1新增一條資料,此時在session2查詢是查不到新增資料的;此時在session1再新建一張表,再去session2查詢,結果發現在session1未執行commit命令的情況下,session2竟然也可以查詢到新增資料了。這是因為session1執行了DDL操作,觸發了隱式提交事務的規則,所以其他session也可以看到DDL的修改了。但是drop命令有點特殊,如果事務還未結束,drop命令會被阻塞。

3.ROLLBACK:回滾事務
Rollback就是與commit相反,不提交事務,可以理解成撤回的意思

mysql> insert into test_a values(1,1);
Query OK, 1 row affected (0.01 sec)

mysql> select * from test_a;
+------+------+
| id1  | id2  |
+------+------+
|    1 |    1 |
+------+------+
1 row in set (0.00 sec)

mysql> rollback;
Query OK, 0 rows affected (0.00 sec)

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