MySQL中隔離級別RC與RR的區(qū)別及說明
MySQL隔離級別RC與RR的區(qū)別
RR 支持 gap lock(next-key lock),而RC則沒有g(shù)ap lock。因為MySQL的RR需要gap lock來解決幻讀問題。而RC隔離級別則是允許存在不可重復(fù)讀和幻讀的。所以RC的并發(fā)一般要好于RR;
RC 隔離級別,通過 where 條件走非索引列過濾之后,不符合條件的記錄上的行鎖,會釋放掉(雖然這里破壞了“兩階段加鎖原則”);但是RR隔離級別,通過 where 條件走非索引列過濾之后,即使不符合where條件的記錄,也是會加行鎖。所以從鎖方面來看,RC的并發(fā)應(yīng)該要好于RR;可以減少一部分鎖競爭,減少死鎖和鎖超時的概率。
RC 隔離級別不支持 statement 格式的bin log,因為該格式的復(fù)制,會導(dǎo)致主從數(shù)據(jù)的不一致;只能使用 mixed 或者 row 格式的bin log; 這也是為什么MySQL默認(rèn)使用RR隔離級別的原因。復(fù)制時,我們最好使用:binlog_format=row
MySQL5.6 的早期版本,RC隔離級別是可以設(shè)置成使用statement格式的bin log,后期版本則會直接報錯;
簡單而且,RC隔離級別時,事務(wù)中的每一條select語句會讀取到他自己執(zhí)行時已經(jīng)提交了的記錄,也就是每一條select都有自己的一致性讀ReadView; 而RR隔離級別時,事務(wù)中的一致性讀的ReadView是以第一條select語句的運行時,作為本事務(wù)的一致性讀snapshot的建立時間點的。只能讀取該時間點之前已經(jīng)提交的數(shù)據(jù)。
MySQL8 RC和RR隔離級別的實戰(zhàn)
讀未提交:在讀未提交這個隔離級別下,即使別的事務(wù)所做的修改并未提交,也能看到其修改的數(shù)據(jù)。當(dāng)事務(wù)的隔離級別處于“讀未提交”時,其并發(fā)性能是最強的,但是隔離性與安全性是最差的,會出現(xiàn)臟讀,在生產(chǎn)環(huán)境中不使用。
讀已提交:讀取數(shù)據(jù)的事務(wù)允許其他事務(wù)繼續(xù)訪問該行數(shù)據(jù),但是未提交的寫事務(wù)將會禁止其他事務(wù)訪問該行。該隔離級別避免了臟讀,但是卻可能出現(xiàn)不可重復(fù)讀。例如,事務(wù)A事先讀取了數(shù)據(jù),事務(wù)B緊接著更新并提交了事務(wù),當(dāng)事務(wù)A再次讀取該數(shù)據(jù)時數(shù)據(jù)已經(jīng)發(fā)生改變。
可重復(fù)讀:是指在一個事務(wù)內(nèi)多次讀同一數(shù)據(jù)。假設(shè)在一個事務(wù)還沒結(jié)束時,另一個事務(wù)也訪問同一數(shù)據(jù),那么在第一個事務(wù)中的兩次讀數(shù)據(jù)之間,即使第二個事務(wù)對數(shù)據(jù)進行了修改,第一個事務(wù)兩次讀到的數(shù)據(jù)也是一樣的。這樣在一個事務(wù)內(nèi)兩次讀到的數(shù)據(jù)就是一樣的,因此稱為可重復(fù)讀。讀取數(shù)據(jù)的事務(wù)禁止寫事務(wù)(但允許讀事務(wù)),寫事務(wù)則禁止任何其他事務(wù),這樣即可避免不可重復(fù)讀和臟讀,但是有時可能出現(xiàn)幻讀。
序列化:提供嚴(yán)格的事務(wù)隔離。它要求事務(wù)序列化執(zhí)行,即事務(wù)只能一個接著一個地執(zhí)行,但不能并發(fā)執(zhí)行。僅僅通過“行級鎖”是無法實現(xiàn)事務(wù)序列化的,必須通過其他機制保證新插入的數(shù)據(jù)不會被剛執(zhí)行查詢操作的事務(wù)訪問到。序列化是最高的事務(wù)隔離級別,同時代價也最高,性能很低,一般很少使用。在該級別下,事務(wù)順序執(zhí)行,不僅可以避免臟讀、不可重復(fù)讀、還避免了幻讀
一、創(chuàng)建測試數(shù)據(jù)
創(chuàng)建測試表:
create table a (id int auto_increment, a varchar(10), b varchar(10), c varchar(10), d varchar(10), ?primary key(id) ) ?engine=INNODB ?default charset=utf8;
插入數(shù)據(jù)
insert into a(a,b,c,d)? values? ('1','1','1','1'), ('2','2','2','2'), ('3','3','3','3'), ('4','4','4','4'), ('5','5','5','5'), ('6','6','6','6');
查詢數(shù)據(jù):
mysql> select * from a; +----+------+------+------+------+ | id | a ? ?| b ? ?| c ? ?| d ? ?| +----+------+------+------+------+ | ?1 | 1 ? ?| 1 ? ?| 1 ? ?| 1 ? ?| | ?2 | 2 ? ?| 2 ? ?| 2 ? ?| 2 ? ?| | ?3 | 3 ? ?| 3 ? ?| 3 ? ?| 3 ? ?| | ?4 | 4 ? ?| 4 ? ?| 4 ? ?| 4 ? ?| | ?5 | 5 ? ?| 5 ? ?| 5 ? ?| 5 ? ?| | ?6 | 6 ? ?| 6 ? ?| 6 ? ?| 6 ? ?| +----+------+------+------+------+ 6 rows in set (0.00 sec)
創(chuàng)建索引:
CREATE INDEX index_b_c ON a(b,c);
二、RR隔離級別
mysql> show variables like '%iso%'; +-----------------------+-----------------+ | Variable_name ? ? ? ? | Value ? ? ? ? ? | +-----------------------+-----------------+ | transaction_isolation | REPEATABLE-READ | +-----------------------+-----------------+ 1 row in set (0.00 sec)
可以從上圖看出,目前MySQL處于RR的隔離級別(可重復(fù)讀)
事務(wù)1:
mysql> begin; Query OK, 0 rows affected (0.00 sec) mysql> update a set d='20' where a='1'; Query OK, 1 row affected (0.00 sec) Rows matched: 1 ?Changed: 1 ?Warnings: 0
事務(wù)2:
mysql> begin; Query OK, 0 rows affected (0.00 sec) mysql> update a set d='20' where a='2';#一直等待,最后報錯 ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
等待時間取決于這個參數(shù):
innodb_lock_wait_timeout
查看mysql鎖情況:
PS:因為show processlist只會顯示出當(dāng)前正在執(zhí)行的語句,有些語句很快就執(zhí)行完成了,所以有時候是看不全的,需要通過系統(tǒng)表查看
performance_schema.data_locks
mysql> select * from performance_schema.data_locks; +--------+---------------------------------------+-----------------------+-----------+----------+---------------+-------------+----------------+-------------------+------------+-----------------------+-----------+-----------+-------------+------------------------+ | ENGINE | ENGINE_LOCK_ID ? ? ? ? ? ? ? ? ? ? ? ?| ENGINE_TRANSACTION_ID | THREAD_ID | EVENT_ID | OBJECT_SCHEMA | OBJECT_NAME | PARTITION_NAME | SUBPARTITION_NAME | INDEX_NAME | OBJECT_INSTANCE_BEGIN | LOCK_TYPE | LOCK_MODE | LOCK_STATUS | LOCK_DATA ? ? ? ? ? ? ?| +--------+---------------------------------------+-----------------------+-----------+----------+---------------+-------------+----------------+-------------------+------------+-----------------------+-----------+-----------+-------------+------------------------+ | INNODB | 140166601014432:1066:140166526246928 ?| ? ? ? ? ? ? ? ? 14257 | ? ? ? 108 | ? ? ? 11 | test ? ? ? ? ?| a ? ? ? ? ? | NULL ? ? ? ? ? | NULL ? ? ? ? ? ? ?| NULL ? ? ? | ? ? ? 140166526246928 | TABLE ? ? | IX ? ? ? ?| GRANTED ? ? | NULL ? ? ? ? ? ? ? ? ? | | INNODB | 140166601014432:5:4:8:140166526244128 | ? ? ? ? ? ? ? ? 14257 | ? ? ? 108 | ? ? ? 11 | test ? ? ? ? ?| a ? ? ? ? ? | NULL ? ? ? ? ? | NULL ? ? ? ? ? ? ?| PRIMARY ? ?| ? ? ? 140166526244128 | RECORD ? ?| X ? ? ? ? | WAITING ? ? | 1 ? ? ? ? ? ? ? ? ? ? ?| | INNODB | 140166601010392:1066:140166526216544 ?| ? ? ? ? ? ? ? ? 14256 | ? ? ? ?76 | ? ? ? 73 | test ? ? ? ? ?| a ? ? ? ? ? | NULL ? ? ? ? ? | NULL ? ? ? ? ? ? ?| NULL ? ? ? | ? ? ? 140166526216544 | TABLE ? ? | IX ? ? ? ?| GRANTED ? ? | NULL ? ? ? ? ? ? ? ? ? | | INNODB | 140166601010392:5:4:1:140166526213552 | ? ? ? ? ? ? ? ? 14256 | ? ? ? ?76 | ? ? ? 73 | test ? ? ? ? ?| a ? ? ? ? ? | NULL ? ? ? ? ? | NULL ? ? ? ? ? ? ?| PRIMARY ? ?| ? ? ? 140166526213552 | RECORD ? ?| X ? ? ? ? | GRANTED ? ? | supremum pseudo-record | | INNODB | 140166601010392:5:4:3:140166526213552 | ? ? ? ? ? ? ? ? 14256 | ? ? ? ?76 | ? ? ? 73 | test ? ? ? ? ?| a ? ? ? ? ? | NULL ? ? ? ? ? | NULL ? ? ? ? ? ? ?| PRIMARY ? ?| ? ? ? 140166526213552 | RECORD ? ?| X ? ? ? ? | GRANTED ? ? | 2 ? ? ? ? ? ? ? ? ? ? ?| | INNODB | 140166601010392:5:4:4:140166526213552 | ? ? ? ? ? ? ? ? 14256 | ? ? ? ?76 | ? ? ? 73 | test ? ? ? ? ?| a ? ? ? ? ? | NULL ? ? ? ? ? | NULL ? ? ? ? ? ? ?| PRIMARY ? ?| ? ? ? 140166526213552 | RECORD ? ?| X ? ? ? ? | GRANTED ? ? | 3 ? ? ? ? ? ? ? ? ? ? ?| | INNODB | 140166601010392:5:4:5:140166526213552 | ? ? ? ? ? ? ? ? 14256 | ? ? ? ?76 | ? ? ? 73 | test ? ? ? ? ?| a ? ? ? ? ? | NULL ? ? ? ? ? | NULL ? ? ? ? ? ? ?| PRIMARY ? ?| ? ? ? 140166526213552 | RECORD ? ?| X ? ? ? ? | GRANTED ? ? | 4 ? ? ? ? ? ? ? ? ? ? ?| | INNODB | 140166601010392:5:4:6:140166526213552 | ? ? ? ? ? ? ? ? 14256 | ? ? ? ?76 | ? ? ? 73 | test ? ? ? ? ?| a ? ? ? ? ? | NULL ? ? ? ? ? | NULL ? ? ? ? ? ? ?| PRIMARY ? ?| ? ? ? 140166526213552 | RECORD ? ?| X ? ? ? ? | GRANTED ? ? | 5 ? ? ? ? ? ? ? ? ? ? ?| | INNODB | 140166601010392:5:4:7:140166526213552 | ? ? ? ? ? ? ? ? 14256 | ? ? ? ?76 | ? ? ? 73 | test ? ? ? ? ?| a ? ? ? ? ? | NULL ? ? ? ? ? | NULL ? ? ? ? ? ? ?| PRIMARY ? ?| ? ? ? 140166526213552 | RECORD ? ?| X ? ? ? ? | GRANTED ? ? | 6 ? ? ? ? ? ? ? ? ? ? ?| | INNODB | 140166601010392:5:4:8:140166526213552 | ? ? ? ? ? ? ? ? 14256 | ? ? ? ?76 | ? ? ? 73 | test ? ? ? ? ?| a ? ? ? ? ? | NULL ? ? ? ? ? | NULL ? ? ? ? ? ? ?| PRIMARY ? ?| ? ? ? 140166526213552 | RECORD ? ?| X ? ? ? ? | GRANTED ? ? | 1 ? ? ? ? ? ? ? ? ? ? ?| +--------+---------------------------------------+-----------------------+-----------+----------+---------------+-------------+----------------+-------------------+------------+-----------------------+-----------+-----------+-------------+------------------------+ 10 rows in set (0.00 sec)
information_schema.INNODB_TRX
mysql> select * from INNODB_TRX\G *************************** 1. row *************************** ? ? ? ? ? ? ? ? ? ? trx_id: 14257 ? ? ? ? ? ? ? ? ?trx_state: LOCK WAIT ? ? ? ? ? ? ? ?trx_started: 2022-04-23 17:09:05 ? ? ?trx_requested_lock_id: 140166601014432:5:4:8:140166526244128 ? ? ? ? ? trx_wait_started: 2022-04-23 17:09:05 ? ? ? ? ? ? ? ? trx_weight: 2 ? ? ? ?trx_mysql_thread_id: 51 ? ? ? ? ? ? ? ? ?trx_query: update a set d='20' where a='2' ? ? ? ?trx_operation_state: starting index read ? ? ? ? ?trx_tables_in_use: 1 ? ? ? ? ?trx_tables_locked: 1 ? ? ? ? ? trx_lock_structs: 2 ? ? ?trx_lock_memory_bytes: 1128 ? ? ? ? ? ?trx_rows_locked: 1 ? ? ? ? ?trx_rows_modified: 0 ? ?trx_concurrency_tickets: 0 ? ? ? ?trx_isolation_level: REPEATABLE READ ? ? ? ? ?trx_unique_checks: 1 ? ? trx_foreign_key_checks: 1 trx_last_foreign_key_error: NULL ?trx_adaptive_hash_latched: 0 ?trx_adaptive_hash_timeout: 0 ? ? ? ? ? trx_is_read_only: 0 trx_autocommit_non_locking: 0 ? ? ? ?trx_schedule_weight: 1 *************************** 2. row *************************** ? ? ? ? ? ? ? ? ? ? trx_id: 14256 ? ? ? ? ? ? ? ? ?trx_state: RUNNING ? ? ? ? ? ? ? ?trx_started: 2022-04-23 17:07:20 ? ? ?trx_requested_lock_id: NULL ? ? ? ? ? trx_wait_started: NULL ? ? ? ? ? ? ? ? trx_weight: 3 ? ? ? ?trx_mysql_thread_id: 26 ? ? ? ? ? ? ? ? ?trx_query: NULL ? ? ? ?trx_operation_state: NULL ? ? ? ? ?trx_tables_in_use: 0 ? ? ? ? ?trx_tables_locked: 1 ? ? ? ? ? trx_lock_structs: 2 ? ? ?trx_lock_memory_bytes: 1128 ? ? ? ? ? ?trx_rows_locked: 7 ? ? ? ? ?trx_rows_modified: 1 ? ?trx_concurrency_tickets: 0 ? ? ? ?trx_isolation_level: REPEATABLE READ ? ? ? ? ?trx_unique_checks: 1 ? ? trx_foreign_key_checks: 1 trx_last_foreign_key_error: NULL ?trx_adaptive_hash_latched: 0 ?trx_adaptive_hash_timeout: 0 ? ? ? ? ? trx_is_read_only: 0 trx_autocommit_non_locking: 0 ? ? ? ?trx_schedule_weight: NULL 2 rows in set (0.00 sec)
從這里可以看到,事務(wù)ID14256正在運行。
performance_schema .data_lock_waits
mysql> select * from data_lock_waits\G *************************** 1. row *************************** ? ? ? ? ? ? ? ? ? ? ? ? ? ENGINE: INNODB ? ? ? ?REQUESTING_ENGINE_LOCK_ID: 140166601014432:5:4:8:140166526244128 REQUESTING_ENGINE_TRANSACTION_ID: 14257 ? ? ? ? ? ? REQUESTING_THREAD_ID: 108 ? ? ? ? ? ? ?REQUESTING_EVENT_ID: 11 REQUESTING_OBJECT_INSTANCE_BEGIN: 140166526244128 ? ? ? ? ?BLOCKING_ENGINE_LOCK_ID: 140166601010392:5:4:8:140166526213552 ? BLOCKING_ENGINE_TRANSACTION_ID: 14256 ? ? ? ? ? ? ? BLOCKING_THREAD_ID: 76 ? ? ? ? ? ? ? ?BLOCKING_EVENT_ID: 73 ? BLOCKING_OBJECT_INSTANCE_BEGIN: 140166526213552 1 row in set (0.00 sec)
從這里可以看到,因為14256事務(wù)ID阻塞了當(dāng)前這個事務(wù)。
從這三張圖可以看出來,第一個事務(wù)正在執(zhí)行(還沒commit),第二個事務(wù)的update處于鎖等待狀態(tài),可能有小伙伴會說,mysql不是行級鎖嗎?為什么update的不是同一條數(shù)據(jù),還是會鎖全表呢?
帶著這個疑問我們來看,下面來看第二個例子:
開啟第一個事務(wù):
mysql> begin; Query OK, 0 rows affected (0.00 sec) mysql> update a set d='20' where b='2';? Query OK, 1 row affected (0.00 sec) Rows matched: 1 ?Changed: 1 ?Warnings: 0
開啟第二個事務(wù):
mysql> begin; Query OK, 0 rows affected (0.00 sec) mysql> update a set d='20' where b='3';? Query OK, 1 row affected (0.00 sec) Rows matched: 1 ?Changed: 1 ?Warnings: 0
思考:為什么這個語句就可以執(zhí)行成功呢?
查看mysql鎖情況:
performance_schema.data_locks mysql> select * from performance_schema.data_locks; +--------+----------------------------------------+-----------------------+-----------+----------+---------------+-------------+----------------+-------------------+------------+-----------------------+-----------+---------------+-------------+-------------+ | ENGINE | ENGINE_LOCK_ID ? ? ? ? ? ? ? ? ? ? ? ? | ENGINE_TRANSACTION_ID | THREAD_ID | EVENT_ID | OBJECT_SCHEMA | OBJECT_NAME | PARTITION_NAME | SUBPARTITION_NAME | INDEX_NAME | OBJECT_INSTANCE_BEGIN | LOCK_TYPE | LOCK_MODE ? ? | LOCK_STATUS | LOCK_DATA ? | +--------+----------------------------------------+-----------------------+-----------+----------+---------------+-------------+----------------+-------------------+------------+-----------------------+-----------+---------------+-------------+-------------+ | INNODB | 140166601010392:1066:140166526216544 ? | ? ? ? ? ? ? ? ? 14266 | ? ? ? 110 | ? ? ? 11 | test ? ? ? ? ?| a ? ? ? ? ? | NULL ? ? ? ? ? | NULL ? ? ? ? ? ? ?| NULL ? ? ? | ? ? ? 140166526216544 | TABLE ? ? | IX ? ? ? ? ? ?| GRANTED ? ? | NULL ? ? ? ?| | INNODB | 140166601010392:5:5:3:140166526213552 ?| ? ? ? ? ? ? ? ? 14266 | ? ? ? 110 | ? ? ? 11 | test ? ? ? ? ?| a ? ? ? ? ? | NULL ? ? ? ? ? | NULL ? ? ? ? ? ? ?| index_b_c ?| ? ? ? 140166526213552 | RECORD ? ?| X ? ? ? ? ? ? | GRANTED ? ? | '2', '2', 2 | | INNODB | 140166601010392:5:4:11:140166526213896 | ? ? ? ? ? ? ? ? 14266 | ? ? ? 110 | ? ? ? 11 | test ? ? ? ? ?| a ? ? ? ? ? | NULL ? ? ? ? ? | NULL ? ? ? ? ? ? ?| PRIMARY ? ?| ? ? ? 140166526213896 | RECORD ? ?| X,REC_NOT_GAP | GRANTED ? ? | 2 ? ? ? ? ? | | INNODB | 140166601010392:5:5:4:140166526214240 ?| ? ? ? ? ? ? ? ? 14266 | ? ? ? 110 | ? ? ? 11 | test ? ? ? ? ?| a ? ? ? ? ? | NULL ? ? ? ? ? | NULL ? ? ? ? ? ? ?| index_b_c ?| ? ? ? 140166526214240 | RECORD ? ?| X,GAP ? ? ? ? | GRANTED ? ? | '3', '3', 3 | +--------+----------------------------------------+-----------------------+-----------+----------+---------------+-------------+----------------+-------------------+------------+-----------------------+-----------+---------------+-------------+-------------+ 4 rows in set (0.00 sec)
information_schema.INNODB_TRX
mysql> select * from INNODB_TRX\G *************************** 1. row *************************** ? ? ? ? ? ? ? ? ? ? trx_id: 14267 ? ? ? ? ? ? ? ? ?trx_state: RUNNING ? ? ? ? ? ? ? ?trx_started: 2022-04-23 17:35:44 ? ? ?trx_requested_lock_id: NULL ? ? ? ? ? trx_wait_started: NULL ? ? ? ? ? ? ? ? trx_weight: 5 ? ? ? ?trx_mysql_thread_id: 51 ? ? ? ? ? ? ? ? ?trx_query: NULL ? ? ? ?trx_operation_state: NULL ? ? ? ? ?trx_tables_in_use: 0 ? ? ? ? ?trx_tables_locked: 1 ? ? ? ? ? trx_lock_structs: 4 ? ? ?trx_lock_memory_bytes: 1128 ? ? ? ? ? ?trx_rows_locked: 3 ? ? ? ? ?trx_rows_modified: 1 ? ?trx_concurrency_tickets: 0 ? ? ? ?trx_isolation_level: REPEATABLE READ ? ? ? ? ?trx_unique_checks: 1 ? ? trx_foreign_key_checks: 1 trx_last_foreign_key_error: NULL ?trx_adaptive_hash_latched: 0 ?trx_adaptive_hash_timeout: 0 ? ? ? ? ? trx_is_read_only: 0 trx_autocommit_non_locking: 0 ? ? ? ?trx_schedule_weight: NULL *************************** 2. row *************************** ? ? ? ? ? ? ? ? ? ? trx_id: 14266 ? ? ? ? ? ? ? ? ?trx_state: RUNNING ? ? ? ? ? ? ? ?trx_started: 2022-04-23 17:30:50 ? ? ?trx_requested_lock_id: NULL ? ? ? ? ? trx_wait_started: NULL ? ? ? ? ? ? ? ? trx_weight: 5 ? ? ? ?trx_mysql_thread_id: 53 ? ? ? ? ? ? ? ? ?trx_query: NULL ? ? ? ?trx_operation_state: NULL ? ? ? ? ?trx_tables_in_use: 0 ? ? ? ? ?trx_tables_locked: 1 ? ? ? ? ? trx_lock_structs: 4 ? ? ?trx_lock_memory_bytes: 1128 ? ? ? ? ? ?trx_rows_locked: 3 ? ? ? ? ?trx_rows_modified: 1 ? ?trx_concurrency_tickets: 0 ? ? ? ?trx_isolation_level: REPEATABLE READ ? ? ? ? ?trx_unique_checks: 1 ? ? trx_foreign_key_checks: 1 trx_last_foreign_key_error: NULL ?trx_adaptive_hash_latched: 0 ?trx_adaptive_hash_timeout: 0 ? ? ? ? ? trx_is_read_only: 0 trx_autocommit_non_locking: 0 ? ? ? ?trx_schedule_weight: NULL 2 rows in set (0.00 sec)
兩個事務(wù)都在正常運行,互不干擾。
performance_schema.data_lock_waits
mysql> select * from performance_schema.data_lock_waits\G Empty set (0.00 sec)
鎖不存在
事務(wù)1提交:
mysql> commit; Query OK, 0 rows affected (0.01 sec) mysql> select * from a; +----+------+------+------+------+ | id | a ? ?| b ? ?| c ? ?| d ? ?| +----+------+------+------+------+ | ?1 | 1 ? ?| 1 ? ?| 1 ? ?| 1 ? ?| | ?2 | 2 ? ?| 2 ? ?| 2 ? ?| 20 ? | | ?3 | 3 ? ?| 3 ? ?| 3 ? ?| 3 ? ?| | ?4 | 4 ? ?| 4 ? ?| 4 ? ?| 4 ? ?| | ?5 | 5 ? ?| 5 ? ?| 5 ? ?| 5 ? ?| | ?6 | 6 ? ?| 6 ? ?| 6 ? ?| 6 ? ?| +----+------+------+------+------+ 6 rows in set (0.00 sec)
從這里可以看出,因為事務(wù)2并沒有提交,所以b=3的數(shù)據(jù)并沒有更新
事務(wù)2提交:
mysql> commit; Query OK, 0 rows affected (0.01 sec) mysql> select * from a; +----+------+------+------+------+ | id | a ? ?| b ? ?| c ? ?| d ? ?| +----+------+------+------+------+ | ?1 | 1 ? ?| 1 ? ?| 1 ? ?| 1 ? ?| | ?2 | 2 ? ?| 2 ? ?| 2 ? ?| 20 ? | | ?3 | 3 ? ?| 3 ? ?| 3 ? ?| 20 ? | | ?4 | 4 ? ?| 4 ? ?| 4 ? ?| 4 ? ?| | ?5 | 5 ? ?| 5 ? ?| 5 ? ?| 5 ? ?| | ?6 | 6 ? ?| 6 ? ?| 6 ? ?| 6 ? ?| +----+------+------+------+------+ 6 rows in set (0.00 sec)
結(jié)論
當(dāng)字段沒有建立索引的時候,該字段作為update條件的話,會鎖全表。
三、RC隔離級別
設(shè)置隔離級別為RC
mysql> set global transaction_isolation='read-committed'
事務(wù)1:
mysql> begin; Query OK, 0 rows affected (0.00 sec) mysql> update a set d='10' where a='1'; Query OK, 1 row affected (0.00 sec) Rows matched: 1 ?Changed: 1 ?Warnings: 0
事務(wù)2:
mysql> begin; Query OK, 0 rows affected (0.00 sec) mysql> update a set d='20' where a='2'; ?? Query OK, 1 row affected (0.00 sec) Rows matched: 1 ?Changed: 1 ?Warnings: 0 mysql> select* from a; +----+------+------+------+------+ | id | a ? ?| b ? ?| c ? ?| d ? ?| +----+------+------+------+------+ | ?1 | 1 ? ?| 1 ? ?| 1 ? ?| 1 ? ?| | ?2 | 2 ? ?| 2 ? ?| 2 ? ?| 20 ? | | ?3 | 3 ? ?| 3 ? ?| 3 ? ?| 3 ? ?| | ?4 | 4 ? ?| 4 ? ?| 4 ? ?| 4 ? ?| | ?5 | 5 ? ?| 5 ? ?| 5 ? ?| 5 ? ?| | ?6 | 6 ? ?| 6 ? ?| 6 ? ?| 6 ? ?| +----+------+------+------+------+ #此時事務(wù)1執(zhí)行commit操作 mysql> select * from a; +----+------+------+------+------+ | id | a ? ?| b ? ?| c ? ?| d ? ?| +----+------+------+------+------+ | ?1 | 1 ? ?| 1 ? ?| 1 ? ?| 10 ? | | ?2 | 2 ? ?| 2 ? ?| 2 ? ?| 20 ? | | ?3 | 3 ? ?| 3 ? ?| 3 ? ?| 3 ? ?| | ?4 | 4 ? ?| 4 ? ?| 4 ? ?| 4 ? ?| | ?5 | 5 ? ?| 5 ? ?| 5 ? ?| 5 ? ?| | ?6 | 6 ? ?| 6 ? ?| 6 ? ?| 6 ? ?| +----+------+------+------+------+ 6 rows in set (0.00 sec)
在RC隔離級別下,并沒有鎖表,可以看到,事務(wù)1在commit情況下,事務(wù)2立刻就可以看到事務(wù)1更新的數(shù)據(jù),這就是不可重復(fù)讀。
mysql> select * from performance_schema.data_locks; +--------+----------------------------------------+-----------------------+-----------+----------+---------------+-------------+----------------+-------------------+------------+-----------------------+-----------+---------------+-------------+-----------+ | ENGINE | ENGINE_LOCK_ID ? ? ? ? ? ? ? ? ? ? ? ? | ENGINE_TRANSACTION_ID | THREAD_ID | EVENT_ID | OBJECT_SCHEMA | OBJECT_NAME | PARTITION_NAME | SUBPARTITION_NAME | INDEX_NAME | OBJECT_INSTANCE_BEGIN | LOCK_TYPE | LOCK_MODE ? ? | LOCK_STATUS | LOCK_DATA | +--------+----------------------------------------+-----------------------+-----------+----------+---------------+-------------+----------------+-------------------+------------+-----------------------+-----------+---------------+-------------+-----------+ | INNODB | 140166601010392:1067:140166526216544 ? | ? ? ? ? ? ? ? ? 14315 | ? ? ? 112 | ? ? ? 22 | test ? ? ? ? ?| a ? ? ? ? ? | NULL ? ? ? ? ? | NULL ? ? ? ? ? ? ?| NULL ? ? ? | ? ? ? 140166526216544 | TABLE ? ? | IX ? ? ? ? ? ?| GRANTED ? ? | NULL ? ? ?| | INNODB | 140166601010392:6:4:10:140166526213552 | ? ? ? ? ? ? ? ? 14315 | ? ? ? 112 | ? ? ? 22 | test ? ? ? ? ?| a ? ? ? ? ? | NULL ? ? ? ? ? | NULL ? ? ? ? ? ? ?| PRIMARY ? ?| ? ? ? 140166526213552 | RECORD ? ?| X,REC_NOT_GAP | GRANTED ? ? | 1 ? ? ? ? | +--------+----------------------------------------+-----------------------+-----------+----------+---------------+-------------+----------------+-------------------+------------+-----------------------+-----------+---------------+-------------+-----------+ 2 rows in set (0.00 sec)
mysql> select * from INNODB_TRX\G *************************** 1. row *************************** ? ? ? ? ? ? ? ? ? ? trx_id: 14316 ? ? ? ? ? ? ? ? ?trx_state: RUNNING ? ? ? ? ? ? ? ?trx_started: 2022-04-23 18:08:55 ? ? ?trx_requested_lock_id: NULL ? ? ? ? ? trx_wait_started: NULL ? ? ? ? ? ? ? ? trx_weight: 3 ? ? ? ?trx_mysql_thread_id: 57 ? ? ? ? ? ? ? ? ?trx_query: NULL ? ? ? ?trx_operation_state: NULL ? ? ? ? ?trx_tables_in_use: 0 ? ? ? ? ?trx_tables_locked: 1 ? ? ? ? ? trx_lock_structs: 2 ? ? ?trx_lock_memory_bytes: 1128 ? ? ? ? ? ?trx_rows_locked: 2 ? ? ? ? ?trx_rows_modified: 1 ? ?trx_concurrency_tickets: 0 ? ? ? ?trx_isolation_level: READ COMMITTED ? ? ? ? ?trx_unique_checks: 1 ? ? trx_foreign_key_checks: 1 trx_last_foreign_key_error: NULL ?trx_adaptive_hash_latched: 0 ?trx_adaptive_hash_timeout: 0 ? ? ? ? ? trx_is_read_only: 0 trx_autocommit_non_locking: 0 ? ? ? ?trx_schedule_weight: NULL *************************** 2. row *************************** ? ? ? ? ? ? ? ? ? ? trx_id: 14315 ? ? ? ? ? ? ? ? ?trx_state: RUNNING ? ? ? ? ? ? ? ?trx_started: 2022-04-23 18:08:04 ? ? ?trx_requested_lock_id: NULL ? ? ? ? ? trx_wait_started: NULL ? ? ? ? ? ? ? ? trx_weight: 3 ? ? ? ?trx_mysql_thread_id: 55 ? ? ? ? ? ? ? ? ?trx_query: NULL ? ? ? ?trx_operation_state: NULL ? ? ? ? ?trx_tables_in_use: 0 ? ? ? ? ?trx_tables_locked: 1 ? ? ? ? ? trx_lock_structs: 2 ? ? ?trx_lock_memory_bytes: 1128 ? ? ? ? ? ?trx_rows_locked: 1 ? ? ? ? ?trx_rows_modified: 1 ? ?trx_concurrency_tickets: 0 ? ? ? ?trx_isolation_level: READ COMMITTED ? ? ? ? ?trx_unique_checks: 1 ? ? trx_foreign_key_checks: 1 trx_last_foreign_key_error: NULL ?trx_adaptive_hash_latched: 0 ?trx_adaptive_hash_timeout: 0 ? ? ? ? ? trx_is_read_only: 0 trx_autocommit_non_locking: 0 ? ? ? ?trx_schedule_weight: NULL 2 rows in set (0.00 sec)
兩個事務(wù)都正常運行。
mysql> select * from data_lock_waits\G Empty set (0.00 sec)
并沒有鎖表
結(jié)論:RC隔離級別下,其實是順序的給每一行都加了鎖的(不是update的數(shù)據(jù)的話,就馬上解開),但是速度非???,如果數(shù)據(jù)量足夠大的話,也是會有l(wèi)ock的。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
關(guān)于mysql中的json解析函數(shù)JSON_EXTRACT
這篇文章主要介紹了關(guān)于mysql中的json解析函數(shù)JSON_EXTRACT講解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-07-07MYSQL使用Union將兩張表的數(shù)據(jù)合并顯示
使用union操作符會將多張表中相同的數(shù)據(jù)取值一次,如果想將表1和表2中的值完整的顯示出來,可以使用union all,今天通過本文給大家分享MYSQL使用Union將兩張表的數(shù)據(jù)合并顯示功能,需要的朋友參考下吧2021-08-08關(guān)于MySQL Memory存儲引擎的相關(guān)知識
這篇文章主要介紹了關(guān)于MySQL Memory存儲引擎的相關(guān)知識,幫助大家更好的理解和使用MySQL數(shù)據(jù)庫,感興趣的朋友可以了解下2020-11-11mysql利用group_concat()合并多行數(shù)據(jù)到一行
把查詢name字段得到的多行記錄進行合并,可以通過程序?qū)崿F(xiàn),但也可直接在sql層完成,需要的朋友可以參考下2014-07-07MySQL與PHP的基礎(chǔ)與應(yīng)用專題之?dāng)?shù)據(jù)完整性
MySQL是一個關(guān)系型數(shù)據(jù)庫管理系統(tǒng),由瑞典MySQL?AB?公司開發(fā),屬于?Oracle?旗下產(chǎn)品。MySQL?是最流行的關(guān)系型數(shù)據(jù)庫管理系統(tǒng)之一,本系列將帶你掌握php與mysql的基礎(chǔ)應(yīng)用,本篇從數(shù)據(jù)完整性開始2022-02-02MySQL命令行界面中出現(xiàn)字符錯誤提示的原因及解決方法
這篇文章主要介紹了MySQL命令行界面中出現(xiàn)字符錯誤提示的原因及解決方法,同時文中還附帶了MySQL導(dǎo)入亂碼問題的解決辦法提示,需要的朋友可以參考下2016-03-03