事務:一組原子性的SQL查詢,或者說一個獨立工做單元。
事務日誌:
在Oracle當中,被分解爲redo log、undo log,及所謂重作日誌和撤銷日誌
ACID測試:
A:atomicity,原子性;整個事務中的全部操做要麼所有成功執行,要麼所有失敗後回滾;
C:conststency,一致性;數據庫老是從一個一致性狀態轉換爲另外一個一致性狀態;
I:Isolation,隔離性;一個事務所作出的操做在提交以前,是不能爲其它所見;
D:durability;持久性;一但事務提交,其所作的修改會永久保存於數據庫中;
隔離有多種隔離級別;
隔離級別越高,數據的安全性越高,不過它的併發能力就越低,隔離級別越低、併發性就越好,可是數據安全性差
事務:
啓動事務:start transaction
結束事務:
一、comit;提交
二、rollback;回滾
注意;只有事務型存儲引擎方能支持此類操做;
建議:顯示請求和提交事務,而不要使用「自動提交」功能;
autocommit={1|0}
示例:
關閉autocommit
MariaDB [hellodb]> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)
MariaDB [hellodb]> show variables like '%auto%';
+--------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------+-------+
| auto_increment_increment | 1 |
| auto_increment_offset | 1 |
| autocommit | OFF |
+--------------------------------------+-------+
開始事務
MariaDB [hellodb]> start transaction;
刪除學生表裏面的stuid是18和23的學員
MariaDB [hellodb]> delete from students where stuid in (18,23);
執行rollback 回滾
MariaDB [hellodb]> rollback;
事務支持savepoint
SAVEPOINT identifier
ROLLBACK [WORK] TO [SAVEPOINT] identifier
RELEASE SAVEPOINT identifier
savepoint示例:
# 開始事務
MariaDB [hellodb]> start transaction;
Query OK, 0 rows affected (0.00 sec)
# 先查看下最初的students表裏面的全部內容
MariaDB [hellodb]> select * from students;
+-------+---------------+-----+--------+---------+-----------+
| StuID | Name | Age | Gender | ClassID | TeacherID |
+-------+---------------+-----+--------+---------+-----------+
| 1 | Shi Zhongyu | 22 | M | 2 | 3 |
| 2 | Shi Potian | 22 | M | 1 | 7 |
| 3 | Xie Yanke | 53 | M | 2 | 16 |
| 4 | Ding Dian | 32 | M | 4 | 4 |
| 5 | Yu Yutong | 26 | M | 3 | 1 |
| 6 | Shi Qing | 46 | M | 5 | NULL |
| 7 | Xi Ren | 19 | F | 3 | NULL |
| 8 | Lin Daiyu | 17 | F | 7 | NULL |
| 9 | Ren Yingying | 20 | F | 6 | NULL |
| 10 | Yue Lingshan | 19 | F | 3 | NULL |
| 11 | Yuan Chengzhi | 23 | M | 6 | NULL |
| 12 | Wen Qingqing | 19 | F | 1 | NULL |
| 13 | Tian Boguang | 33 | M | 2 | NULL |
| 14 | Lu Wushuang | 17 | F | 3 | NULL |
| 15 | Duan Yu | 19 | M | 4 | NULL |
| 16 | Xu Zhu | 21 | M | 1 | NULL |
| 17 | Lin Chong | 25 | M | 4 | NULL |
| 18 | Hua Rong | 23 | M | 7 | NULL |
| 19 | Xue Baochai | 18 | F | 6 | NULL |
| 20 | Diao Chan | 19 | F | 7 | NULL |
| 21 | Huang Yueying | 22 | F | 6 | NULL |
| 22 | Xiao Qiao | 20 | F | 1 | NULL |
| 23 | Ma Chao | 23 | M | 4 | NULL |
| 24 | Xu Xian | 27 | M | NULL | NULL |
| 25 | Sun Dasheng | 100 | M | NULL | NULL |
+-------+---------------+-----+--------+---------+-----------+
25 rows in set (0.00 sec)
# 執行delete語句刪除學員編號爲18的學員信息
MariaDB [hellodb]> delete from students where stuid=18;
Query OK, 1 row affected (0.00 sec)
# 建立一個事務還原點爲sp1
MariaDB [hellodb]> savepoint sp1;
Query OK, 0 rows affected (0.00 sec)
# 插入一條信息
MariaDB [hellodb]> insert into students (name,age,gender) values('Jinjiao King',100,'M');
Query OK, 1 row affected (0.00 sec)
# 建立一個事務還原點爲sp2
MariaDB [hellodb]> savepoint sp2;
Query OK, 0 rows affected (0.00 sec)
# 使用update語句更新13號學員的年齡
MariaDB [hellodb]> update students set age=43 where stuid=13;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
# 上述操做作完以後查看下錶是否發生變化
MariaDB [hellodb]> select * from students;
+-------+---------------+-----+--------+---------+-----------+
| StuID | Name | Age | Gender | ClassID | TeacherID |
+-------+---------------+-----+--------+---------+-----------+
| 1 | Shi Zhongyu | 22 | M | 2 | 3 |
| 2 | Shi Potian | 22 | M | 1 | 7 |
| 3 | Xie Yanke | 53 | M | 2 | 16 |
| 4 | Ding Dian | 32 | M | 4 | 4 |
| 5 | Yu Yutong | 26 | M | 3 | 1 |
| 6 | Shi Qing | 46 | M | 5 | NULL |
| 7 | Xi Ren | 19 | F | 3 | NULL |
| 8 | Lin Daiyu | 17 | F | 7 | NULL |
| 9 | Ren Yingying | 20 | F | 6 | NULL |
| 10 | Yue Lingshan | 19 | F | 3 | NULL |
| 11 | Yuan Chengzhi | 23 | M | 6 | NULL |
| 12 | Wen Qingqing | 19 | F | 1 | NULL |
| 13 | Tian Boguang | 43 | M | 2 | NULL |
| 14 | Lu Wushuang | 17 | F | 3 | NULL |
| 15 | Duan Yu | 19 | M | 4 | NULL |
| 16 | Xu Zhu | 21 | M | 1 | NULL |
| 17 | Lin Chong | 25 | M | 4 | NULL |
| 19 | Xue Baochai | 18 | F | 6 | NULL |
| 20 | Diao Chan | 19 | F | 7 | NULL |
| 21 | Huang Yueying | 22 | F | 6 | NULL |
| 22 | Xiao Qiao | 20 | F | 1 | NULL |
| 23 | Ma Chao | 23 | M | 4 | NULL |
| 24 | Xu Xian | 27 | M | NULL | NULL |
| 25 | Sun Dasheng | 100 | M | NULL | NULL |
| 26 | Jinjiao King | 100 | M | NULL | NULL |
+-------+---------------+-----+--------+---------+-----------+
25 rows in set (0.00 sec)
# 對students操做完以後,假如說其中有數據有問題,而後回到以前建立的sp2上
MariaDB [hellodb]> rollback to sp2;
Query OK, 0 rows affected (0.00 sec)
MariaDB [hellodb]> select * from students;
+-------+---------------+-----+--------+---------+-----------+
| StuID | Name | Age | Gender | ClassID | TeacherID |
+-------+---------------+-----+--------+---------+-----------+
| 1 | Shi Zhongyu | 22 | M | 2 | 3 |
| 2 | Shi Potian | 22 | M | 1 | 7 |
| 3 | Xie Yanke | 53 | M | 2 | 16 |
| 4 | Ding Dian | 32 | M | 4 | 4 |
| 5 | Yu Yutong | 26 | M | 3 | 1 |
| 6 | Shi Qing | 46 | M | 5 | NULL |
| 7 | Xi Ren | 19 | F | 3 | NULL |
| 8 | Lin Daiyu | 17 | F | 7 | NULL |
| 9 | Ren Yingying | 20 | F | 6 | NULL |
| 10 | Yue Lingshan | 19 | F | 3 | NULL |
| 11 | Yuan Chengzhi | 23 | M | 6 | NULL |
| 12 | Wen Qingqing | 19 | F | 1 | NULL |
| 13 | Tian Boguang | 33 | M | 2 | NULL |
| 14 | Lu Wushuang | 17 | F | 3 | NULL |
| 15 | Duan Yu | 19 | M | 4 | NULL |
| 16 | Xu Zhu | 21 | M | 1 | NULL |
| 17 | Lin Chong | 25 | M | 4 | NULL |
| 19 | Xue Baochai | 18 | F | 6 | NULL |
| 20 | Diao Chan | 19 | F | 7 | NULL |
| 21 | Huang Yueying | 22 | F | 6 | NULL |
| 22 | Xiao Qiao | 20 | F | 1 | NULL |
| 23 | Ma Chao | 23 | M | 4 | NULL |
| 24 | Xu Xian | 27 | M | NULL | NULL |
| 25 | Sun Dasheng | 100 | M | NULL | NULL |
| 26 | Jinjiao King | 100 | M | NULL | NULL |
+-------+---------------+-----+--------+---------+-----------+
25 rows in set (0.00 sec)
# 回滾到以前建立sp1的狀態上
MariaDB [hellodb]> rollback to sp1;
Query OK, 0 rows affected (0.00 sec)
# 所有回滾到最初狀態
MariaDB [hellodb]> rollback;
Query OK, 0 rows affected (0.00 sec)
事務隔離級別
事務隔離級別:
事務自己是須要隔離的,但隔離作的過於嚴格,任何一個事務都會阻塞其它訪問同一個資源的事務,爲了不事務過多的影響其所謂的併發性,咱們對事務關係型標準當中對事務的隔離等級作定義,每一種關係型數據庫,均可以設定本身到底支持哪一種級別,大多數數據庫默認狀況下都支持到第二種,但mysql支持第三級別
事務的四種隔離級別:(mysql默認是REPEATABLE READ 可重複讀)
READ UNCOMMITED (讀未提交)
髒讀、不可重複讀、幻讀
READ COMMITTED (讀提交)
不可重複讀、幻讀
REPEATABLE READ (可重讀)
幻讀
SERIALIZABILE (可串行化)
加鎖讀
可能存在問題:
髒讀: 讀別人未提交的數據
不可重複讀: 讀別人提交的數據也能夠,可是別人提交之後產生一個問題查看的結果是以前看到的數據,看不到後面提交的新數據,不可重複讀,兩次讀到的數據是不同的
幻讀: 即讀取過程當中,即便有其它提交的事務修改數據,仍只能讀取到未修改前的舊數據。
加鎖讀:
tx_isolation:服務器變量,默認爲REPEATABLE-READ;可在session級別進行修改
MVCC:多版本併發控制
死鎖:
兩個或多個事務在同一資源相互佔用,並請求鎖定對方佔用的資源的狀態;
數據庫爲了解決這樣的問題,設計了各類死鎖檢測、和死鎖超時時長
事務日誌:
事務日誌的寫入類型爲「追加」、所以其操做爲「順序IO」,此日誌一般也被稱爲「預寫式日誌(write ahead logging)」;
innodb_log_file_size
innodb_log_files_in_group
innodb_log_group_home_dir
事務的隔離級別示例:
髒讀實驗:
爲了實驗效果多開一個會話窗口,而且兩邊都把autocommit自動提交事務給關閉掉
MariaDB [hellodb]> set autocommit=0;
MariaDB [hellodb]> show variables like '%auto%';
+------------------------------+-------+
| Variable_name | Value |
+------------------------------+-------+
| auto_increment_increment | 1 |
| auto_increment_offset | 1 |
| autocommit | OFF |
+------------------------------+-------+
一、把兩個會話改成READ-UNCOMMITTED模式;
MariaDB [hellodb]> show global variables like '%isola%';
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| tx_isolation | REPEATABLE-READ |
+---------------+-----------------+
1 row in set (0.00 sec)
MariaDB [hellodb]> set tx_isolation='READ-UNCOMMITTED';
Query OK, 0 rows affected (0.00 sec)
在兩個會話上都啓用事務
MariaDB [hellodb]> start transaction;
Query OK, 0 rows affected (0.00 sec)
在第一個會話中修改students表裏面的13號學員的年齡爲40
MariaDB [hellodb]> update students set age=40 where stuid=13;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
MariaDB [hellodb]> select * from students where stuid=13;
+-------+--------------+-----+--------+---------+-----------+
| StuID | Name | Age | Gender | ClassID | TeacherID |
+-------+--------------+-----+--------+---------+-----------+
| 13 | Tian Boguang | 40 | M | 2 | NULL |
+-------+--------------+-----+--------+---------+-----------+
1 row in set (0.00 sec)
而後在第二個會話裏面查看是否是能看到13號學員的修改後的數據庫此時第一個窗口並未提交事務
MariaDB [hellodb]> select * from students where stuid=13;
+-------+--------------+-----+--------+---------+-----------+
| StuID | Name | Age | Gender | ClassID | TeacherID |
+-------+--------------+-----+--------+---------+-----------+
| 13 | Tian Boguang | 40 | M | 2 | NULL |
+-------+--------------+-----+--------+---------+-----------+
1 row in set (0.00 sec)
----------------------------------------------------------------------------------------
REPEATABLE-READ模式:
設置爲REPEATABLE-READ
MariaDB [hellodb]> set tx_isolation='REPEATABLE-READ';
Query OK, 0 rows affected (0.00 sec)
刪除stuid爲3的學員
MariaDB [hellodb]> delete from students where stuid=3;
Query OK, 1 row affected (0.00 sec)
在第一會話提交事務
MariaDB [hellodb]> commit;
Query OK, 0 rows affected (0.00 sec)
在第一會話查詢stuid爲3的已經查不到了
MariaDB [hellodb]> select * from students where stuid=3;
Empty set (0.00 sec)
在第二個會話中查詢仍是能夠查詢到,這就產生了幻讀,這種模式解決了不可重複讀,不過仍是避免不了幻讀的問題
MariaDB [hellodb]> select * from students where stuid = 3;
+-------+-----------+-----+--------+---------+-----------+
| StuID | Name | Age | Gender | ClassID | TeacherID |
+-------+-----------+-----+--------+---------+-----------+
| 3 | Xie Yanke | 53 | M | 2 | 16 |
+-------+-----------+-----+--------+---------+-----------+
1 row in set (0.00 sec)
只有在第二會話中執行提交事務以後再次查詢就沒有出現了
MariaDB [hellodb]> commit;
Query OK, 0 rows affected (0.00 sec)
MariaDB [hellodb]> select * from students where stuid=3;
Empty set (0.00 sec)
----------------------------------------------------------------------------------
SERIALIZABLE 加鎖讀示例:
一、設置模式爲SERIALIZABLE
MariaDB [hellodb]> set tx_isolation='SERIALIZABLE';
Query OK, 0 rows affected (0.00 sec)
二、修改stuid爲14的年齡
MariaDB [hellodb]> update students set age=21 where stuid=14;
三、在本窗口查詢修改結果
MariaDB [hellodb]> select * from students where stuid=14;
+-------+-------------+-----+--------+---------+-----------+
| StuID | Name | Age | Gender | ClassID | TeacherID |
+-------+-------------+-----+--------+---------+-----------+
| 14 | Lu Wushuang | 21 | F | 3 | NULL |
+-------+-------------+-----+--------+---------+-----------+
四、在第二個會話窗口查詢,只要執行查詢以後就會被阻塞,而後過了必定時長系統會提示超時
MariaDB [hellodb]> select * from students;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
五、第一窗口執行提交事務
MariaDB [hellodb]> commit;
Query OK, 0 rows affected (0.02 sec)
六、再在第二窗口查詢,就能夠查詢
MariaDB [hellodb]> select * from students where stuid=14;
+-------+-------------+-----+--------+---------+-----------+
| StuID | Name | Age | Gender | ClassID | TeacherID |
+-------+-------------+-----+--------+---------+-----------+
| 14 | Lu Wushuang | 21 | F | 3 | NULL |
+-------+-------------+-----+--------+---------+-----------+
1 row in set (0.00 sec)