- 事務(wù)
mysql中事務(wù)其實是一個最小的不可分割的工作單位。事務(wù)能保證一個業(yè)務(wù)的完整性。
比如我們的銀行轉(zhuǎn)帳:
a -> -100 update user set money=money-100 where name='a';
b -> +100 update user set money=money+100 where name='b';
若只有一條語句成功執(zhí)行,而另外一條執(zhí)行失敗,會出現(xiàn)數(shù)據(jù)前后不一致的情況。
事務(wù)的作用就是讓多條sql語句要么同時成功,要么同時失敗(可以使用rollback進行回滾)。 - 如何控制事務(wù)
mysql默認開啟了一個自動提交的事務(wù),當(dāng)我們?nèi)?zhí)行一個sql語句的時候,執(zhí)行效果會立即體現(xiàn)出來,且不能回滾。
mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
| 1 |
+--------------+
1 row in set (0.05 sec)
- 關(guān)閉了自動提交的事務(wù),就可以回滾(撤銷sql語句執(zhí)行的效果)
mysql> set autocommit=0;
Query OK, 0 rows affected (0.07 sec)
mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
| 0 |
+--------------+
1 row in set (0.00 sec)
mysql> insert into milk values(3,'mengniu');
Query OK, 1 row affected (0.01 sec)
mysql> select * from milk;
+----+---------+
| id | name |
+----+---------+
| 1 | yili |
| 2 | yili |
| 3 | mengniu |
+----+---------+
3 rows in set (0.00 sec)
mysql> rollback;
Query OK, 0 rows affected (0.01 sec)
mysql> select * from milk;
+----+------+
| id | name |
+----+------+
| 1 | yili |
| 2 | yili |
+----+------+
2 rows in set (0.00 sec)
- 撤銷自動提交之后,上面插入的數(shù)據(jù)并未真實的插入milk表中,只是在一張?zhí)摂M的表中(臨時表)實現(xiàn)了插入效果,所以才可以進行回滾。手動使用commit提交數(shù)據(jù),一旦提交之后就不可以進行撤銷(持久性):
mysql> insert into milk values(3,'mengniu');
Query OK, 1 row affected (0.00 sec)
mysql> commit;
Query OK, 0 rows affected (0.02 sec)
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from milk;
+----+---------+
| id | name |
+----+---------+
| 1 | yili |
| 2 | yili |
| 3 | mengniu |
+----+---------+
3 rows in set (0.00 sec)
- 手動開啟事務(wù)(begin或者start transaction)
手動開啟事務(wù)但不使用commit提交,就可以回滾
事務(wù)開啟之后,一旦commit提交,就不可以回滾(也就是當(dāng)前的這個事務(wù)在提交的時候就結(jié)束了)
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into milk values(4,'mengniu');
Query OK, 1 row affected (0.00 sec)
mysql> select * from milk;
+----+---------+
| id | name |
+----+---------+
| 1 | yili |
| 2 | yili |
| 3 | mengniu |
| 4 | mengniu |
+----+---------+
4 rows in set (0.00 sec)
mysql> rollback;
Query OK, 0 rows affected (0.01 sec)
mysql> select * from milk;
+----+---------+
| id | name |
+----+---------+
| 1 | yili |
| 2 | yili |
| 3 | mengniu |
+----+---------+
3 rows in set (0.00 sec)
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into milk values(4,'mengniu');
Query OK, 1 row affected (0.00 sec)
mysql> rollback;
Query OK, 0 rows affected (0.01 sec)
mysql> select * from milk;
+----+---------+
| id | name |
+----+---------+
| 1 | yili |
| 2 | yili |
| 3 | mengniu |
+----+---------+
3 rows in set (0.00 sec)
- 總結(jié)
事務(wù)的開啟:
(1) 修改默認提交 set autocommit=0;
(2) begin;
(3) start transaction;
事務(wù)手動提交:commit;
事務(wù)手動回滾:rollback;
- 事務(wù)的ACID特征
A 原子性:事務(wù)是最小的單位,不可以再分割
C 一致性:同一事務(wù)中的sql語句,必須保證同時成功或同時失敗
I 隔離性:事務(wù)一和事務(wù)二之間是具有隔離性的
D 持久性:事務(wù)一旦結(jié)束就不可返回
4.1 查看隔離級別:
mysql 5.5:
- 會話級別的查詢
mysql> select @@tx_isolation;
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set (0.00 sec)
- 系統(tǒng)級別的查詢
mysql> select @@global.tx_isolation;
+-----------------------+
| @@global.tx_isolation |
+-----------------------+
| REPEATABLE-READ |
+-----------------------+
1 row in set (0.00 sec)
mysql 8.0:
- 會話級別的查詢
mysql> select @@transaction_isolation;
- 系統(tǒng)級別的查詢
mysql> select @@global.transaction_isolation;
4.2 如何修改隔離級別
- read uncommited; 讀未提交的
- read committed; 讀已經(jīng)提交的
- repeatable read; 可以重復(fù)讀
- serializable; 串行化
mysql> set global transaction isolation level read uncommitted;
Query OK, 0 rows affected (0.00 sec)
mysql> select @@global.tx_isolation;
+-----------------------+
| @@global.tx_isolation |
+-----------------------+
| READ-UNCOMMITTED |
+-----------------------+
1 row in set (0.00 sec)
如果兩個不同的地方,都在進行操作,如果事務(wù)a開啟之后,它的數(shù)據(jù)可以被其他事務(wù)讀取到,這樣就會出現(xiàn)臟讀。臟讀就是一個事務(wù)讀到了另外一個事務(wù)沒有提交的數(shù)據(jù)。實際開發(fā)是不允許臟讀出現(xiàn)的。
不可重復(fù)讀:事務(wù) A 多次讀取同一數(shù)據(jù),事務(wù) B 在事務(wù)A多次讀取的過程中,對數(shù)據(jù)作了更新并提交,導(dǎo)致事務(wù)A多次讀取同一數(shù)據(jù)時,結(jié)果不一致。
幻讀:系統(tǒng)管理員A將數(shù)據(jù)庫中所有學(xué)生的成績從具體分數(shù)改為ABCDE等級,但是系統(tǒng)管理員B就在這個時候插入了一條具體分數(shù)的記錄,當(dāng)系統(tǒng)管理員A改結(jié)束后發(fā)現(xiàn)還有一條記錄沒有改過來,就好像發(fā)生了幻覺一樣,這就叫幻讀。
| 事務(wù)隔離級別 | 臟讀 | 不可重復(fù)讀 | 幻讀 |
|---|---|---|---|
| 讀未提交(read-uncommitted) | 是 | 是 | 是 |
| 不可重復(fù)讀(read-committed) | 否 | 是 | 是 |
| 可重復(fù)讀(repeatable-read) | 否 | 否 | 是 |
| 串行化(serializable) | 否 | 否 | 否 |
隔離級別越高,性能越差。