for update相當于加了一個行鎖
會命中d = 5的這一行吊说,對應的主鍵是id等于5,因此在select語句執(zhí)行完后d=5的這一行會加一個寫鎖优炬,那么由于我們這個兩階段鎖的協(xié)議呢颁井,這個寫鎖會執(zhí)行commit語句的時候進行一個釋放。
在mysql innoDB的默認級別是可重復讀
幻讀:一個事務在前后兩次查詢同一個范圍蠢护,或者說查詢同一條語句的時候雅宾,后一次查詢看到了前一次看不到的東西。
比如說葵硕,我有兩個事務A和B眉抬,A執(zhí)行了好多次
select * from t where d = 5 for update;
,B在這個表里insert了d=5的東西
懈凹,再次select的時候前一次執(zhí)行和后一次執(zhí)行看到的事務就不一樣了(幻讀)蜀变。在可重復讀級別下,普通的查詢是我們的快照查詢介评,不會看到其它事務插入的數(shù)據(jù)库北。因此幻讀在當前讀下才會出現(xiàn)。
幻讀僅指新插入的行,而不是update的行贤惯。
什么叫做當前讀,當前讀就指上面說的
for update
棒掠。雖然給這行加鎖孵构,也它也要說看到這行最新的數(shù)據(jù),for update
這里也叫做我們的當前讀烟很。因為更新之前必須先查詢一下當前的值颈墅。select in share modle
也是一個當前讀的東西,指在更新之前必須先查詢一下當前的值雾袱,所以叫做當前讀恤筛。快照讀只是在語句執(zhí)行之前或者事務開始的時候芹橡,創(chuàng)建一個視圖然后毒坛,后面的讀呢都是基于這個視圖來讀的,像我們說的版本號似的林说,不會查詢這個最新的值煎殷。for update
會查詢最新的值,那出現(xiàn)幻讀怎么辦呢腿箩。for update
肯定是想把d = 5這行給鎖住豪直。有了幻讀之后,這個語句的語義就被破壞了珠移,這個鎖的目的是保證數(shù)據(jù)的前后一致性弓乙,這樣也破壞了這個一致性。幻讀產(chǎn)生的原因是行鎖只能鎖住當前這一行钧惧,我還可以往里面再Insert東西暇韧,并不能去鎖住其它的行。所以這里我們引出了另外的一個鎖——間隙鎖浓瞪。
1 5 10 ,比如當前查詢的這個值為5它會把前這個值的前一位和后一位都給鎖住锨咙。