1. 程式人生 > >MySQL事務+FOR UPDATE解決併發操作資料庫

MySQL事務+FOR UPDATE解決併發操作資料庫

注意 FOR UPDATE 僅適用於InnoDB,且必須在事務區塊(BEGIN/COMMIT)中才能生效。

由於InnoDB 預設是Row-Level Lock,所以只有「明確」的指定主鍵,MySQL 才會執行Row lock (只鎖住被選取的資料) ,否則MySQL 將會執行Table Lock (將整個資料表單給鎖住)。

例如下面幾種情況

A.假設有個表單products ,裡面有id 跟name 二個欄位,id 是主鍵。

(明確指定主鍵,並且有此資料,row lock也就是行鎖)

SELECT * FROM products WHERE id='3' FOR UPDATE;

B.(明確指定主鍵,若查無此資料,無lock)

SELECT * FROM products WHERE id='-1' FOR UPDATE;

C.(無主鍵,table lock)

SELECT * FROM products WHERE name='Mouse' FOR UPDATE;

D .(主鍵不明確,table lock)

SELECT * FROM products WHERE id<>'3' FOR UPDATE;

SELECT * FROM products WHERE id LIKE '3' FOR UPDATE;

要測試鎖定的狀況,可以利用MySQL 的Command Mode ,開二個視窗來做測試

MySQL update && select

CREATE TABLE `testupdate` (

`id` bigint(20) NOT NULL AUTO_INCREMENT,

`val` bigint(20) NOT NULL DEFAULT '0',

PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8

update testupdate

set val = val+1

where id = 1 and @value := val+1;

select @value;