事务的隔离级别有4种: SQL-1992 ,但是我只想介绍其中两种,因为其他的两个根本就用不上
就拿上面那个简单的例子来佐证好了
RR 如何解决幻读问题?RR 的锁算法:next-key lock
解决幻读的案例 dba:lc_4> set tx_isolation='repeatable-read'; Query OK, 0 rows affected (0.00 sec) dba:lc_4> select * from lc for update ; +----+ | id | +----+ | 1 | | 2 | | 3 | +----+ 3 rows in set (0.00 sec) 这时候,查看下锁的情况: ------------ TRANSACTIONS ------------ Trx id counter 133588361 Purge done for trx's n:o < 133588356 undo n:o < 0 state: running but idle History list length 892 LIST OF TRANSACTIONS FOR EACH SESSION: ---TRANSACTION 421565826150000, not started 0 lock struct(s), heap size 1136, 0 row lock(s) ---TRANSACTION 421565826149088, not started 0 lock struct(s), heap size 1136, 0 row lock(s) ---TRANSACTION 133588360, ACTIVE 4 sec 2 lock struct(s), heap size 1136, 4 row lock(s) MySQL thread id 135, OS thread handle 140001104295680, query id 1176 localhost dba cleaning up TABLE LOCK table `lc_4`.`lc` trx id 133588360 lock mode IX RECORD LOCKS space id 289 page no 3 n bits 72 index PRIMARY of table `lc_4`.`lc` trx id 133588360 lock_mode X --next key lock , 锁记录和范围 Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0 0: len 8; hex 73757072656d756d; asc supremum;; --next-key lock, 锁住正无穷大 Record lock, heap no 2 PHYSICAL RECORD: n_fields 3; compact format; info bits 0 0: len 4; hex 80000001; asc ;; --next-key lock, 锁住1和1之前的区间,包括记录 (negtive,1] 1: len 6; hex 000007f6657e; asc e~;; 2: len 7; hex e5000040220110; asc @" ;; Record lock, heap no 3 PHYSICAL RECORD: n_fields 3; compact format; info bits 0 0: len 4; hex 80000002; asc ;; --next-key lock, 锁住2和1之前的区间,包括记录 (1,2] 1: len 6; hex 000007f6657f; asc e ;; 2: len 7; hex e6000040330110; asc @3 ;; Record lock, heap no 4 PHYSICAL RECORD: n_fields 3; compact format; info bits 0 0: len 4; hex 80000003; asc ;; --next-key lock, 锁住3和2之间的区间,包括记录 (2,3] 1: len 6; hex 000007f66584; asc e ;; 2: len 7; hex e9000040240110; asc @$ ;; * 总结下来就是: 1. (negtive bounds,1] , (1,2] , (2,3],(3,positive bounds) --锁住的记录和范围,相当于表锁 2. 这时候,session 2 插入任何一条记录,会被锁住,所以幻读可以避免,尤其彻底解决了幻读的问题RC 的锁算法:record locks幻读对线上影响大吗? oracle默认就是RC隔离级别
不解决幻读的案例 dba:lc_4> set tx_isolation='read-committed'; Query OK, 0 rows affected (0.00 sec) dba:lc_4> select * from lc for update ; +----+ | id | +----+ | 1 | | 2 | | 3 | +----+ 3 rows in set (0.00 sec) * 查看锁的信息如下 ------------ TRANSACTIONS ------------ Trx id counter 133588362 Purge done for trx's n:o < 133588356 undo n:o < 0 state: running but idle History list length 892 LIST OF TRANSACTIONS FOR EACH SESSION: ---TRANSACTION 421565826150000, not started 0 lock struct(s), heap size 1136, 0 row lock(s) ---TRANSACTION 421565826149088, not started 0 lock struct(s), heap size 1136, 0 row lock(s) ---TRANSACTION 133588361, ACTIVE 3 sec 2 lock struct(s), heap size 1136, 3 row lock(s) MySQL thread id 138, OS thread handle 140001238955776, query id 1192 localhost dba cleaning up TABLE LOCK table `lc_4`.`lc` trx id 133588361 lock mode IX RECORD LOCKS space id 289 page no 3 n bits 72 index PRIMARY of table `lc_4`.`lc` trx id 133588361 lock_mode X locks rec but not gap --记录锁,只锁记录 Record lock, heap no 2 PHYSICAL RECORD: n_fields 3; compact format; info bits 0 0: len 4; hex 80000001; asc ;; -- 记录锁,锁住1 1: len 6; hex 000007f6657e; asc e~;; 2: len 7; hex e5000040220110; asc @" ;; Record lock, heap no 3 PHYSICAL RECORD: n_fields 3; compact format; info bits 0 0: len 4; hex 80000002; asc ;; -- 记录锁,锁住2 1: len 6; hex 000007f6657f; asc e ;; 2: len 7; hex e6000040330110; asc @3 ;; Record lock, heap no 4 PHYSICAL RECORD: n_fields 3; compact format; info bits 0 0: len 4; hex 80000003; asc ;; -- 记录锁,锁住3 1: len 6; hex 000007f66584; asc e ;; 2: len 7; hex e9000040240110; asc @$ ;; * 总结下来 1. 锁住的是哪些? [1,2,3] 这些记录被锁住 2. 那么session 2 除了1,2,3 不能插入之外,其他的记录都能,比如; insert into lc select 4 , 那么再次select * from lc for udpate 的时候,就是4条记录了,由此产生幻读