今天來用 sql 實際體會一下悲觀鎖
一樣先reference一下原文(其實原文寫得更濃縮,如果希望一次吸收多一點歡迎直接看原文也是鐵人賽)
先開一個sql editor出來
先看一下當前事物隔離等級
SHOW VARIABLES LIKE 'transaction_isolation';
---'transaction_isolation', 'REPEATABLE-READ'
REPEATABLE-READ 是MySQL的預設事物隔離級別,關於事物隔離級別有四個,可以先簡單想成自動管理鎖的行為,例如 select for update 之後,可不可以讀寫,會讀寫到什麼數據,會根據設定的隔離級別來自動有不同的管理方式,目的就是避免資料不一致,但可能又會想說,那為什麼不用最嚴格的隔離級別,既然有四個等級,因為越嚴格的隔離級別,效能最低(併發量最低,畢竟鎖越多,併發數就越低)
先來直接邊做lab邊了解悲觀鎖,事物隔離後面會有篇幅來專門介紹
CREATE TABLE orders (
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(45) NOT NULL,
`num` INT NOT NULL,
PRIMARY KEY (`id`)
);
INSERT INTO orders (`name`,`num`)
VALUES ("iphone",1);
A session
begin;
select num from orders where id = 1 for update;
B session
begin;
select num from orders where id = 1 for update;
此時會發現 B session 卡住,感覺像有一個無限迴圈卡著等待,因為目前 id=1 這一個 row 被鎖住了,這個叫做行鎖(所以也還會有表鎖或是全局鎖),就是把一行資料鎖住不讓其他人更動,除非當前解鎖。
接著
A session
update orders set num = 0 where id = 1;
commit;
這時候 B就可以 select 到值了為0,這樣就不會結帳下去了,避免了超賣。實務上自己也還沒用程式做過,只有看文章下sql實驗機制,不過鎖的觀念應該是通用的,這偏就做這個悲觀鎖小練習!
下面一篇來做樂觀鎖