MYSQL INNODB 鎖錶小研究

2022-09-12 08:45:11 字數 2963 閱讀 8463

表結構如下:

delimiter $$

create table `wrox_shop_order` (

`o_id` int(11) not null auto_increment,

`order_date` datetime default null,

`order_status` varchar(45) default 'created',

`customer_id` int(11) default null,

primary key (`o_id`),

key `orderdate` (`order_date`) //這裡最開始不加,後面添上的

) engine=innodb auto_increment=164 default charset=utf8$$

這樣乙個資料表:

開啟兩個mysql客戶端:

因為工作需要 我在mysql workbench裡面用了乙個 儲存過程,相對簡單的乙個:

delimiter $$

/××××param1 表示輸入的值,param2,param3 是輸出變數:後面使用

××select @m1 

as a,@m2 as b; 可以得到輸出的值

××/

create procedure last_delete_info (in param1 datetime,out param2 int,out param3 varchar(45))

begin

select o_id,order_status into param2,param3 from wrox_shop_order where order_date=param1 limit 1 for

update;

#delete from wrox_shop_order where o_id=param2; //這一行後面用@delete來表示

end$$

delimiter ;

首先在workbench裡執行:

操作一:

set autocommit=0;

call last_delete_info('2013-04-01 19:49:58',@m1,@m2);

select @m1

as a,@m2 as b;

結果:

此時 o_id 為3的行是否被鎖住了呢?開啟mysql 命令列到相應資料庫中執行:

操作二:

delete from wrox_shop_order where o_id=3;

結果刪除不了資料,說明該行資料被加了鎖,那麼刪除其他資料呢?

delete from wrox_shop_order where o_id=4 or o_id=5; 

結果還是刪除不了資料,

從這裡我們驗證了很多人都驗證的問題,如果innodb 沒有在加索引的行上加鎖,那麼會使用表鎖

接下來如果有注意最開始的建立語句有這麼乙個:key `orderdate` (`order_date`) //這裡最開始不加,後面添上的

那麼現在去個order_date加個索引:

alter table `test`.`wrox_shop_order` 

add index `order_date` (`order_date` asc) ;

然後重新執行上面兩個mysql客戶端工具的操作,執行到第二步的時候命令列還是無法刪除,但是如果刪除其他資料卻是可以的

說明innodb在加了索引的的行上加鎖是加的行級鎖,而且是對索引加的鎖

今天又做了一些測試,再次總結一下:

比如:

delimiter $$

create table `akulubala` (

`id` int(11) not null auto_increment,

`artist` varchar(100) not null,

`title` varchar(100) not null,

`index_column` tinyint,

primary key (`id`),

key `index_c` (`index_column`)

) engine=innodb auto_increment=7 default charset=utf8$$

執行:set autocommit=0;

select * from akulubala.akulubala where index_column=9 for update;

另外乙個程序執行:

select * from akulubala.akulubala where index_column=9 for update; 這裡會出現等待。需等待第乙個程序commit;

update akulubala set title='s' where index_column=?; 這裡不管id !=9 就可以執行  (說明索引被加了鎖)

update akulubala set artist = 'aaaaa' where id = 4;這裡 只要id 行沒有在前乙個程序搜尋的結果中 就不會等待 

由以上三點可以得出鎖是對索引的鎖,即對索引加鎖,使用被加鎖的索引時都會等待,並且對由索引查出的行加鎖,如果更新資料沒有用到任何索引,就會全表加鎖..

update akulubala set artist='ttt' where id=3;如果id=3不在前乙個程序的查詢結果中就 可以執行;

單純的查詢如select * from akulubala 是查出所有資料

另外:事務和鎖是兩回事,事務有四個隔離級別,不同的隔離級別有不同的鎖定機制:innodb 預設是可重複讀

mysql InnoDB引擎的行鎖和表鎖

之前是有接觸行鎖和表鎖但是由於沒有實際應用過也只是大概了解,前兩天就遇到了併發同時對一條記錄進行修改。mysql肯定會讓修改請求排隊,也就是說加了鎖,但是mysql預設加的是表鎖,但是會影響效率,所以我們需要用行鎖。表鎖 顧名思義就是對整張表進行加鎖,同一時刻整張表所有記錄都被霸佔,雖然不會出現死鎖...

MySQL InnoDB引擎的行鎖和表鎖

1.行鎖和表鎖 在mysql 的 innodb引擎支援行鎖,與oracle不同,mysql的行鎖是通過索引載入的,即是行鎖是加在索引響應的行上的,要是對應的sql語句沒有走索引,則會全表掃瞄,行鎖則無法實現,取而代之的是表鎖。2.連表鎖機制 在連表操作中,雙方表選中的所以行當中一旦有一條在鎖定中,則...

MySQL InnoDB鎖問題(四)

一 innodb行鎖實現方式。innodb行鎖是通過給索引上的索引項來加鎖實現的,如果沒有索引,innodb將通過隱藏的聚簇索引來對記錄加鎖。innodb行鎖分三種情形。1 record lock 對索引項加鎖。2 grap lock 對索引項之間的 間隙 第一條記錄前的 間隙 或者最後一條記錄後的...