學習了這篇文章:https://www.cnblogs.com/jian-gao/p/10795407.html
事務的 四個特征(ACID)
事務具有四個特征:原子性( Atomicity )、一致性( Consistency )、隔離性( Isolation )和持續性( Durability )。這四個特性簡稱為 ACID 特性。
1 、原子性。事務是數據庫的邏輯工作單位,事務中包含的各操作要么都做,要么都不做
2 、一致性。事 務執行的結果必須是使數據庫從一個一致性狀態變到另一個一致性狀態。因此當數據庫只包含成功事務提交的結果時,就說數據庫處於一致性狀態。如果數據庫系統 運行中發生故障,有些事務尚未完成就被迫中斷,這些未完成事務對數據庫所做的修改有一部分已寫入物理數據庫,這時數據庫就處於一種不正確的狀態,或者說是 不一致的狀態。
3 、隔離性。一個事務的執行不能其它事務干擾。即一個事務內部的操作及使用的數據對其它並發事務是隔離的,並發執行的各個事務之間不能互相干擾。
4 、持續性。也稱永久性,指一個事務一旦提交,它對數據庫中的數據的改變就應該是永久性的。接下來的其它操作或故障不應該對其執行結果有任何影響。
關於四種隔離mysql參考文檔是這么描述的:
15.7.2.1事務隔離級別
事務隔離是數據庫處理的基礎之一。隔離是縮寫ACID中的I ; 隔離級別是一種設置,用於在多個事務同時進行更改和執行查詢時微調性能與結果的可靠性,一致性和可重復性之間的平衡。
InnoDB提供
由SQL描述的所有四個事務隔離級別:1992標准: READ UNCOMMITTED
, READ COMMITTED
, REPEATABLE READ
,和 SERIALIZABLE
。默認隔離級別InnoDB
是 REPEATABLE READ
。
用戶可以使用該SET TRANSACTION
語句更改單個會話或所有后續連接的隔離級別。要為所有連接設置服務器的默認隔離級別,請--transaction-isolation
在命令行或選項文件中使用該 選項。有關隔離級別和級別設置語法的詳細信息,請參見 第13.3.7節“ SET TRANSACTION語句”。
InnoDB
支持使用不同的鎖定策略在此描述的每個事務隔離級別 。您可以在默認數據REPEATABLE READ
級別上實現高度一致性 ,以便在重要的數據上執行 ACID合規性。或者,在批量報告之類的情況下,精確的一致性和可重復的結果與最小化鎖定開銷相比不那么重要,您READ COMMITTED
甚至可以放寬一致性規則,甚至 可以放寬一致性規則 READ UNCOMMITTED
。 SERIALIZABLE
實施比甚至更嚴格的規則REPEATABLE READ
,並且主要用於特殊情況下(例如XA)事務以及用於解決並發和死鎖問題 。
下表描述了MySQL如何支持不同的事務級別。列表從最常用的級別到最不常用的級別。
感興趣的可以去看:https://dev.mysql.com/doc/refman/8.0/en/innodb-transaction-isolation-levels.html
Mysql的四種隔離級別
SQL標准定義了4類隔離級別,包括了一些具體規則,用來限定事務內外的哪些改變是可見的,哪些是不可見的。低級別的隔離級一般支持更高的並發處理,並擁有更低的系統開銷。
Read Uncommitted(讀取未提交內容)
在該隔離級別,所有事務都可以看到其他未提交事務的執行結果。本隔離級別很少用於實際應用,因為它的性能也不比其他級別好多少。讀取未提交的數據,也被稱之為臟讀(Dirty Read)。
Read Committed(讀取提交內容)
這是大多數數據庫系統的默認隔離級別(但不是MySQL默認的)。它滿足了隔離的簡單定義:一個事務只能看見已經提交事務所做的改變。這種隔離級別 也支持所謂的不可重復讀(Nonrepeatable Read),因為同一事務的其他實例在該實例處理其間可能會有新的commit,所以同一select可能返回不同結果。
Repeatable Read(可重讀)
這是MySQL的默認事務隔離級別,它確保同一事務的多個實例在並發讀取數據時,會看到同樣的數據行。不過理論上,這會導致另一個棘手的問題:幻讀 (Phantom Read)。簡單的說,幻讀指當用戶讀取某一范圍的數據行時,另一個事務又在該范圍內插入了新行,當用戶再讀取該范圍的數據行時,會發現有新的“幻影” 行。InnoDB和Falcon存儲引擎通過多版本並發控制(MVCC,Multiversion Concurrency Control)機制解決了該問題。
Serializable(可串行化)
這是最高的隔離級別,它通過強制事務排序,使之不可能相互沖突,從而解決幻讀問題。簡言之,它是在每個讀的數據行上加上共享鎖。在這個級別,可能導致大量的超時現象和鎖競爭。
出現問題
這四種隔離級別采取不同的鎖類型來實現,若讀取的是同一個數據的話,就容易發生問題。例如:
臟讀(Drity Read):某個事務已更新一份數據,另一個事務在此時讀取了同一份數據,由於某些原因,前一個RollBack了操作,則后一個事務所讀取的數據就會是不正確的。
不可重復讀(Non-repeatable read):在一個事務的兩次查詢之中數據不一致,這可能是兩次查詢過程中間插入了一個事務更新的原有的數據。
幻讀(Phantom Read):在一個事務的兩次查詢中數據筆數不一致,例如有一個事務查詢了幾列(Row)數據,而另一個事務卻在此時插入了新的幾列數據,先前的事務在接下來的查詢中,就會發現有幾列數據是它先前所沒有的。
在MySQL中,實現了這四種隔離級別,分別有可能產生問題如下所示:
接下來我按照文章中方法在本地測試環境測試下Mysql的隔離級別
Read Uncommitted(讀取未提交內容)
下面,將利用MySQL的客戶端程序,我們分別來測試一下這幾種隔離級別。
測試數據庫為company,表為customers4;表結構:
mysql> desc customers4; +--------------+-----------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------------+-----------+------+-----+---------+-------+ | cust_id | int(11) | NO | | 0 | | | cust_name | char(50) | NO | | NULL | | | cust_address | char(50) | YES | | NULL | | | cust_city | char(50) | YES | | NULL | | | cust_state | char(5) | YES | | NULL | | | cust_zip | char(10) | YES | | NULL | | | cust_country | char(50) | YES | | NULL | | | cust_contact | char(50) | YES | | NULL | | | cust_email | char(255) | YES | | NULL | | +--------------+-----------+------+-----+---------+-------+ 9 rows in set (0.00 sec) mysql>
(一)、將A的隔離級別設置為read uncommitted(未提交讀)
set session transaction isolation level read uncommitted;
查看隔離級別是否設置成功
select @@transaction_isolation (mysql版本 8.0 以后)
select @@tx_isolation (mysql版本 8.0 之前)
查看mysql版本
> status
A:啟動事務,此時數據為初始狀態
start transaction;
B:啟動事務,更新數據,但不提交
start transaction;
A:再次讀取數據,發現數據已經被修改了,這就是所謂的“臟讀”
A客戶端:
mysql> mysql> use company; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> select @@transaction_isolation; +-------------------------+ | @@transaction_isolation | +-------------------------+ | REPEATABLE-READ | +-------------------------+ 1 row in set (0.00 sec) mysql> set session transaction isolation level read uncommitted; Query OK, 0 rows affected (0.00 sec) mysql> select @@transaction_isolation; +-------------------------+ | @@transaction_isolation | +-------------------------+ | READ-UNCOMMITTED | +-------------------------+ 1 row in set (0.00 sec) mysql> start transaction; Query OK, 0 rows affected (0.00 sec) mysql> select * from customers4; +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+------------+ | cust_id | cust_name | cust_address | cust_city | cust_state | cust_zip | cust_country | cust_contact | cust_email | +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+------------+ | 1 | spider_man | 中國深圳龍崗區 | 深圳 | NULL | NULL | NULL | NULL | NULL | | 2 | big | 中國深圳南山區 | 深圳 | NULL | NULL | NULL | NULL | NULL | +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+------------+ 2 rows in set (0.00 sec) mysql> select * from customers4; +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+------------+ | cust_id | cust_name | cust_address | cust_city | cust_state | cust_zip | cust_country | cust_contact | cust_email | +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+------------+ | 1 | spider_man | 中國深圳龍崗區 | 深圳 | NULL | NULL | NULL | NULL | NULL | | 2 | woman | 中國深圳南山區 | 深圳 | NULL | NULL | NULL | NULL | NULL | +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+------------+ 2 rows in set (0.00 sec) mysql>
B客戶端:
mysql> use company; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> select * from customers4; +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+------------+ | cust_id | cust_name | cust_address | cust_city | cust_state | cust_zip | cust_country | cust_contact | cust_email | +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+------------+ | 1 | spider_man | 中國深圳龍崗區 | 深圳 | NULL | NULL | NULL | NULL | NULL | | 2 | big | 中國深圳南山區 | 深圳 | NULL | NULL | NULL | NULL | NULL | +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+------------+ 2 rows in set (0.00 sec) mysql> show create table customers4; +------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Table | Create Table | +------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | customers4 | CREATE TABLE `customers4` ( `cust_id` int(11) NOT NULL DEFAULT '0', `cust_name` char(50) CHARACTER SET utf8 NOT NULL, `cust_address` char(50) CHARACTER SET utf8 DEFAULT NULL, `cust_city` char(50) CHARACTER SET utf8 DEFAULT NULL, `cust_state` char(5) CHARACTER SET utf8 DEFAULT NULL, `cust_zip` char(10) CHARACTER SET utf8 DEFAULT NULL, `cust_country` char(50) CHARACTER SET utf8 DEFAULT NULL, `cust_contact` char(50) CHARACTER SET utf8 DEFAULT NULL, `cust_email` char(255) CHARACTER SET utf8 DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci | +------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec) mysql> start transaction; Query OK, 0 rows affected (0.00 sec) mysql> select * from customers4; +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+------------+ | cust_id | cust_name | cust_address | cust_city | cust_state | cust_zip | cust_country | cust_contact | cust_email | +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+------------+ | 1 | spider_man | 中國深圳龍崗區 | 深圳 | NULL | NULL | NULL | NULL | NULL | | 2 | big | 中國深圳南山區 | 深圳 | NULL | NULL | NULL | NULL | NULL | +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+------------+ 2 rows in set (0.00 sec) mysql> update customers4 set cust_name='woman' where cust_id=2; Query OK, 1 row affected (0.04 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql>
這時B客戶端rollback:
mysql> rollback; Query OK, 0 rows affected (0.00 sec) mysql> select * from customers4; +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+------------+ | cust_id | cust_name | cust_address | cust_city | cust_state | cust_zip | cust_country | cust_contact | cust_email | +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+------------+ | 1 | spider_man | 中國深圳龍崗區 | 深圳 | NULL | NULL | NULL | NULL | NULL | | 2 | big | 中國深圳南山區 | 深圳 | NULL | NULL | NULL | NULL | NULL | +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+------------+ 2 rows in set (0.00 sec) mysql>
A客戶端查看結果也變了,那么之前讀取的數據就是 ‘臟讀’
mysql> select * from customers4; +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+------------+ | cust_id | cust_name | cust_address | cust_city | cust_state | cust_zip | cust_country | cust_contact | cust_email | +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+------------+ | 1 | spider_man | 中國深圳龍崗區 | 深圳 | NULL | NULL | NULL | NULL | NULL | | 2 | big | 中國深圳南山區 | 深圳 | NULL | NULL | NULL | NULL | NULL | +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+------------+ 2 rows in set (0.00 sec) mysql>
經過上面的實驗可以得出結論,事務B更新了一條記錄,但是沒有提交,此時事務A可以查詢出未提交記錄。造成臟讀現象。未提交讀是最低的隔離級別。
(二)、將客戶端A的事務隔離級別設置為read committed(已提交讀)
set session transaction isolation level read committed;
A:啟動事務,此時數據為初始狀態
B:啟動事務,更新數據,但不提交
A:再次讀數據,發現數據未被修改
B:提交事務
A:再次讀取數據,發現數據已發生變化,說明B提交的修改被事務中的A讀到了,這就是所謂的“不可重復讀”
A客戶端:
mysql> set session transaction isolation level read committed; Query OK, 0 rows affected (0.00 sec) mysql> select @@transaction_isolation; +-------------------------+ | @@transaction_isolation | +-------------------------+ | READ-COMMITTED | +-------------------------+ 1 row in set (0.00 sec) mysql> commit; Query OK, 0 rows affected (0.00 sec) mysql> start transaction; Query OK, 0 rows affected (0.01 sec) mysql> select @@transaction_isolation; +-------------------------+ | @@transaction_isolation | +-------------------------+ | READ-COMMITTED | +-------------------------+ 1 row in set (0.00 sec) mysql> select * from customers4; +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+------------+ | cust_id | cust_name | cust_address | cust_city | cust_state | cust_zip | cust_country | cust_contact | cust_email | +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+------------+ | 1 | spider_man | 中國深圳龍崗區 | 深圳 | NULL | NULL | NULL | NULL | | | 2 | big | 中國深圳南山區 | 深圳 | NULL | NULL | NULL | NULL | NULL | +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+------------+ 2 rows in set (0.00 sec) mysql>
B客戶端,這時update后還未commit,A客戶端在事務中查到的還是舊數據
mysql> start transaction; Query OK, 0 rows affected (0.00 sec) mysql> update customers4 set cust_email='AAA@szkingdom.com' where cust_name='spider_man'; Query OK, 1 row affected (0.07 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> commit;
Query OK, 0 rows affected (0.09 sec)
B客戶端commit后,再在A客戶端查看:
mysql> select * from customers4; +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+-------------------+ | cust_id | cust_name | cust_address | cust_city | cust_state | cust_zip | cust_country | cust_contact | cust_email | +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+-------------------+ | 1 | spider_man | 中國深圳龍崗區 | 深圳 | NULL | NULL | NULL | NULL | AAA@szkingdom.com | | 2 | big | 中國深圳南山區 | 深圳 | NULL | NULL | NULL | NULL | NULL | +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+-------------------+ 2 rows in set (0.00 sec) mysql>
經過上面的實驗可以得出結論,已提交讀隔離級別解決了臟讀的問題,但是出現了不可重復讀的問題,即事務A在兩次查詢的數據不一致,因為在兩次查詢之間事務B更新了一條數據。已提交讀只允許讀取已提交的記錄,但不要求可重復讀。
(三)、將A的隔離級別設置為repeatable read(可重復讀)
A:啟動事務,此時數據為初始狀態
B:啟動事務,更新數據,但不提交
A:再次讀取數據,發現數據未被修改
B:提交事務
A:再次讀取數據,發現數據依然未發生變化,這說明這次可以重復讀了
B:插入一條新的數據,並提交
A:再次讀取數據,發現數據依然未發生變化,雖然可以重復讀了,但是卻發現讀的不是最新數據,這就是所謂的“幻讀”
A:提交本次事務,再次讀取數據,發現讀取正常了
A客戶端:
mysql> select @@transaction_isolation; +-------------------------+ | @@transaction_isolation | +-------------------------+ | READ-COMMITTED | +-------------------------+ 1 row in set (0.00 sec) mysql> set session transaction isolation level repeatable read; Query OK, 0 rows affected (0.00 sec) mysql> select @@transaction_isolation; +-------------------------+ | @@transaction_isolation | +-------------------------+ | REPEATABLE-READ | +-------------------------+ 1 row in set (0.00 sec) mysql> start transaction; Query OK, 0 rows affected (0.00 sec) mysql> select * from customers4; +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+-------------------+ | cust_id | cust_name | cust_address | cust_city | cust_state | cust_zip | cust_country | cust_contact | cust_email | +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+-------------------+ | 1 | spider_man | 中國深圳龍崗區 | 深圳 | NULL | NULL | NULL | NULL | AAA@szkingdom.com | | 2 | big | 中國深圳南山區 | 深圳 | NULL | NULL | NULL | NULL | NULL | +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+-------------------+ 2 rows in set (0.00 sec) mysql>
B客戶端:
mysql> select * from customers4; +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+-------------------+ | cust_id | cust_name | cust_address | cust_city | cust_state | cust_zip | cust_country | cust_contact | cust_email | +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+-------------------+ | 1 | spider_man | 中國深圳龍崗區 | 深圳 | NULL | NULL | NULL | NULL | AAA@szkingdom.com | | 2 | big | 中國深圳南山區 | 深圳 | NULL | NULL | NULL | NULL | NULL | +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+-------------------+ 2 rows in set (0.00 sec) mysql> start transaction; Query OK, 0 rows affected (0.00 sec) mysql> update customers4 set cust_contact='13545467358' where cust_id=1; Query OK, 1 row affected (0.05 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql>
B客戶端提交后:
mysql> update customers4 set cust_contact='13545467358' where cust_id=1; Query OK, 1 row affected (0.05 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> commit; Query OK, 0 rows affected (0.09 sec) mysql> select * from customers4; +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+-------------------+ | cust_id | cust_name | cust_address | cust_city | cust_state | cust_zip | cust_country | cust_contact | cust_email | +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+-------------------+ | 1 | spider_man | 中國深圳龍崗區 | 深圳 | NULL | NULL | NULL | 13545467358 | AAA@szkingdom.com | | 2 | big | 中國深圳南山區 | 深圳 | NULL | NULL | NULL | NULL | NULL | +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+-------------------+ 2 rows in set (0.00 sec) mysql>
A客戶端查詢還是沒變,退出事務后才變:
mysql> select * from customers4; +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+-------------------+ | cust_id | cust_name | cust_address | cust_city | cust_state | cust_zip | cust_country | cust_contact | cust_email | +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+-------------------+ | 1 | spider_man | 中國深圳龍崗區 | 深圳 | NULL | NULL | NULL | NULL | AAA@szkingdom.com | | 2 | big | 中國深圳南山區 | 深圳 | NULL | NULL | NULL | NULL | NULL | +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+-------------------+ 2 rows in set (0.00 sec) mysql> commit; Query OK, 0 rows affected (0.00 sec) mysql> select * from customers4; +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+-------------------+ | cust_id | cust_name | cust_address | cust_city | cust_state | cust_zip | cust_country | cust_contact | cust_email | +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+-------------------+ | 1 | spider_man | 中國深圳龍崗區 | 深圳 | NULL | NULL | NULL | 13545467358 | AAA@szkingdom.com | | 2 | big | 中國深圳南山區 | 深圳 | NULL | NULL | NULL | NULL | NULL | +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+-------------------+ 2 rows in set (0.00 sec)
由以上的實驗可以得出結論,可重復讀隔離級別只允許讀取已提交記錄,而且在一個事務兩次讀取一個記錄期間,其他事務部的更新該記錄。但該事務不要求與其他事務可串行化。例如,當一個事務可以找到由一個已提交事務更新的記錄,但是可能產生幻讀問題(注意是可能,因為數據庫對隔離級別的實現有所差別)。像以上的實驗,就沒有出現數據幻讀的問題
(四)、將A的隔離級別設置為可串行化(Serializable)
A:啟動事務,此時數據為初始狀態
B:發現B此時進入了等待狀態,原因是因為A的事務尚未提交,只能等待(此時,B可能會發生等待超時)
A:提交事務
B:發現插入成功
A客戶端:
mysql> set session transaction isolation level serializable; Query OK, 0 rows affected (0.28 sec) mysql> start transaction; Query OK, 0 rows affected (0.00 sec) mysql> select * from customers4; +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+-------------------+ | cust_id | cust_name | cust_address | cust_city | cust_state | cust_zip | cust_country | cust_contact | cust_email | +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+-------------------+ | 1 | spider_man | 中國深圳龍崗區 | 深圳 | NULL | NULL | NULL | 13545467358 | AAA@szkingdom.com | | 2 | big | 中國深圳南山區 | 深圳 | NULL | NULL | NULL | NULL | NULL | +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+-------------------+ 2 rows in set (0.00 sec) mysql>
B客戶端:
mysql> start transaction; Query OK, 0 rows affected (0.00 sec) mysql> select * from customers4; +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+-------------------+ | cust_id | cust_name | cust_address | cust_city | cust_state | cust_zip | cust_country | cust_contact | cust_email | +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+-------------------+ | 1 | spider_man | 中國深圳龍崗區 | 深圳 | NULL | NULL | NULL | 13545467358 | AAA@szkingdom.com | | 2 | big | 中國深圳南山區 | 深圳 | NULL | NULL | NULL | NULL | NULL | +---------+------------+-----------------------+-----------+------------+----------+--------------+--------------+-------------------+ 2 rows in set (0.00 sec) mysql>
A客戶端,update未提交:
mysql> update customers4 set cust_country='China' where cust_id=1; Query OK, 1 row affected (0.05 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql>
B客戶端,先進入等待,最后超時:
mysql> update customers4 set cust_country='China' where cust_id=1; Query OK, 1 row affected (0.05 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql>
CERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
在超時時間內,當A commit,B緊跟着update成功。
serializable完全鎖定字段,若一個事務來查詢同一份數據就必須等待,直到前一個事務完成並解除鎖定為止。是完整的隔離級別,會鎖定對應的數據表格,因而會有效率的問題。