關于設計圖的網(wǎng)站天津seo排名扣費
目錄
1.為什么要有隔離性
2.事務的隔離級別
讀未提交
讀提交
可重復讀
串行化
3.演示事務隔離級別的操作
查看與設置事務的隔離級別
演示讀提交操作
演示可重復讀操作
1.為什么要有隔離性
? ? ? ? 在真正的業(yè)務場景下,MySQL服務在同一時間一定會有大量的客戶端進程并發(fā)的去訪問同一個MySQL服務,而且一定會同一時間有多個客戶端訪問和操作同一張表。而且我們在業(yè)務層面,一個事務很多情況下都需要多條SQL語句組成,那么這樣的話,操作雖然是原子性的,但是過程卻可以明顯的分成執(zhí)行前、執(zhí)行中以及執(zhí)行后三個階段。
????????那么在執(zhí)行中的階段,一個客戶端在執(zhí)行事務操作數(shù)據(jù)庫表,但是事務還沒有完成提交,其其他客戶端如果查看到該客戶端沒有提交的數(shù)據(jù),會不會有問題呢?如果客戶端查看了另一個客戶端沒有提交的數(shù)據(jù),但是另一個客戶端最后執(zhí)行了回滾操作,那么該客戶端查看的數(shù)據(jù)就不是真實的數(shù)據(jù)了,出現(xiàn)了數(shù)據(jù)的二義性。
? ? ? ? 所以說為了保證數(shù)據(jù)庫在執(zhí)行事務操作過程中盡量不受到干擾,就有了一個重要的特性就是隔離性。但是也并非客戶端在執(zhí)行事務的時候,不能讓其他客戶端查看自己沒有提交的數(shù)據(jù),在一些更關注數(shù)據(jù)的實時性的業(yè)務操作中,就能夠接受短暫的數(shù)據(jù)不一致問題。
2.事務的隔離級別
? ? ? ? 事務的隔離級別分為讀未提交、讀提交、可重復讀、串行化,不同的隔離界別可以讓蛇舞收到不同程度的干擾,可以用于不同的業(yè)務場景。對于隔離級別的實現(xiàn)基本上都是通過鎖實現(xiàn)了,因為多客戶端訪問也相當于是多線程的并發(fā)訪問,所以說還是要用鎖。對于不同的隔離級別,鎖的使用是不同的,常見的有表鎖、行鎖、讀鎖、寫鎖等等。
? ? ? ? 對于事務的隔離級別是相對于自己而言的,如果說一個客戶端A是讀未提交,客戶端B是讀提交,那么客戶端B想要提取客戶端A在事務中操作的結(jié)果就需要在客戶端A提交之后才可以看得到。
讀未提交
? ? ? ? 該隔離級別屬于是最低的隔離界別,相當于沒隔離一樣,所有的事物都可以看到其他事物沒有提交的執(zhí)行結(jié)果,這種隔離界別在實際的業(yè)務中基本上是不會使用的。會有很多的并發(fā)問題,例如臟讀、幻讀、不可重復讀等問題。
臟讀 | 一個事務讀取到了另一個事務未提交的操作結(jié)果就是臟讀。由于未提交的事務數(shù)據(jù)可能回因為事務的回滾而改變,所以讀到的數(shù)據(jù)可能回出問題。 |
幻讀 | 在一個事務內(nèi),按照某個條件進行數(shù)據(jù)查詢的時候,第一次查詢和第二次查詢的結(jié)果集不同??赡苁且驗槠渌聞赵谶@個期間對數(shù)據(jù)進行了操作。 |
不可重復讀 | 在一個事務內(nèi),對于同一個數(shù)據(jù)的多次讀取結(jié)果不一致叫做不可重復讀??赡芤驗樵谠撌聞請?zhí)行期間,其他事務對這個數(shù)據(jù)進行了修改等操作,導致了讀取數(shù)據(jù)的變化,造成了該問題。 |
? ? ? ? 臟讀更加聚焦于數(shù)據(jù)的插入和刪除操作,兩次查看的數(shù)據(jù)量不一樣,而不可重復讀更聚焦于數(shù)據(jù)的修改和刪除的操作,兩次查看的數(shù)據(jù)量可能一樣,但是里面的數(shù)據(jù)不一樣。
讀提交
? ? ? ? 該隔離級別是大多數(shù)數(shù)據(jù)庫的默認隔離級別(但不是MySQL的),也是普遍理解上最合適的一個隔離級別。該隔離級別規(guī)定了,一個事務只能看到其他的已經(jīng)提交的事務所改變的數(shù)據(jù)操作。這種級別的隔離就不會產(chǎn)數(shù)據(jù)的臟讀問題了。因為只能讀取到提交之后的存放在磁盤當中的永久化數(shù)據(jù)。但是還是會有不同重復讀取的問題,因為多次查看表數(shù)據(jù)的時候,在此其他其他事務可能回修改表并提交事務。
可重復讀
? ? ? ? 這是MySQL的默認隔離級別,他確保同一個事務,在執(zhí)行的過程中多次讀取操作數(shù)據(jù)的時候,回看到同樣的數(shù)據(jù)行。使得數(shù)據(jù)不會出現(xiàn)臟讀、不可重復讀取的問題,但是會有幻讀的問題。
串行化
? ? ? ? 串行化是數(shù)據(jù)庫事務隔離級別中最高的級別。在串行化隔離級別下,事務的執(zhí)行是順序的,一個事務必須等待前一個事務完成(提交或者回滾)之后才能開始執(zhí)行,在等待過程中就會放入等待隊列。就好像多個事務是在一條單行道上排隊依次通過一樣,完全避免了并發(fā)事務之間的相互干擾。他會在每個讀的數(shù)據(jù)行上面加上共享鎖,但是加鎖就會有鎖的競爭問題,會大大降低效率。這種級別不會有任何的事務之間相互影響的問題了。
3.演示事務隔離級別的操作
查看與設置事務的隔離級別
? ? ? ? 事務隔離級別的設置分為全局的和會話級別的設置,如果設置會話級別的話,就相當于是對于一個客戶端連接的設置,關閉之后再重啟還是會重制事務的隔離級別,會按照全局的事務隔離界別來定義。
? ? ? ? 對于設置會話級別的事務隔離性不需要重啟服務器,但是設置全局級別話需要重啟,因為事務的隔離級別是受會話影響的,客戶端啟動的會話隔離級別是從全局隔離級別復制過來的,所以說全局隔離級別決定了客戶端啟動的時候的事務隔離級別,但是事務在操作的時候,是看會話的事務隔離級別的。
查看語法:SELECT @@[SESSION | GLOBAL].TRANSACTION_ISOLATION;
設置語法:SELECT [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL { READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE };
演示讀提交操作
//客戶但A————————————————————————————————————————————————————————
//設置會話隔離級別為讀提交
mysql> set session transaction isolation level read committed;
Query OK, 0 rows affected (0.00 sec)//開啟事務
mysql> begin;
Query OK, 0 rows affected (0.00 sec)//插入與提交事務
mysql> insert into account values(1, '張三', 100), (2, '李四', 200);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0mysql> commit;
Query OK, 0 rows affected (0.01 sec)//客戶但B————————————————————————————————————————————————————————
//設置會話隔離級別為讀提交
mysql> set session transaction isolation level read committed;
Query OK, 0 rows affected (0.00 sec)//開啟事務
mysql> begin;
Query OK, 0 rows affected (0.00 sec)//在客戶端A提交之前查看表數(shù)據(jù)
mysql> select * from account;
Empty set (0.00 sec)//在客戶端A提交之后查看表數(shù)據(jù)
mysql> select * from account;
+----+--------+--------+
| id | name | blance |
+----+--------+--------+
| 1 | 張三 | 100.00 |
| 2 | 李四 | 200.00 |
+----+--------+--------+
2 rows in set (0.00 sec)//提交數(shù)據(jù)
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
? ? ? ? 該操作,客戶端B在事務期間,兩次查看表數(shù)據(jù)的數(shù)據(jù)不一樣,這就是不可重復讀。
演示可重復讀操作
//客戶但A————————————————————————————————————————————————————————
//設置會話隔離級別為可重復讀
mysql> set session transaction isolation level repeatable read;
Query OK, 0 rows affected (0.00 sec)//開啟事務,插入數(shù)據(jù),提交事務
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into account values(3, '王五', 300);
Query OK, 1 row affected (0.00 sec)
mysql> commit;
Query OK, 0 rows affected (0.00 sec)//客戶但B————————————————————————————————————————————————————————
//設置會話隔離級別為可重復讀
mysql> set session transaction isolation level repeatable read;
Query OK, 0 rows affected (0.00 sec)//開啟事務
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
//客戶端A提交之前
mysql> select * from account;
+----+--------+--------+
| id | name | blance |
+----+--------+--------+
| 1 | 張三 | 100.00 |
| 2 | 李四 | 200.00 |
+----+--------+--------+
2 rows in set (0.00 sec)//客戶端A提交之后
mysql> select * from account;
+----+--------+--------+
| id | name | blance |
+----+--------+--------+
| 1 | 張三 | 100.00 |
| 2 | 李四 | 200.00 |
+----+--------+--------+
2 rows in set (0.00 sec)//提交事務
mysql> commit;
Query OK, 0 rows affected (0.00 sec)//自己提交事務之后查看表數(shù)據(jù)
mysql> select * from account;
+----+--------+--------+
| id | name | blance |
+----+--------+--------+
| 1 | 張三 | 100.00 |
| 2 | 李四 | 200.00 |
| 3 | 王五 | 300.00 |
+----+--------+--------+
3 rows in set (0.00 sec)