表結構如下:
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 @m1as a,@m2 as b; 可以得到輸出的值
××/首先在workbench裡執行: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 ;
操作一:
set autocommit=0;此時 o_id 為3的行是否被鎖住了呢?開啟mysql 命令列到相應資料庫中執行:call last_delete_info('2013-04-01 19:49:58',@m1,@m2);
select @m1
as a,@m2 as b;
結果:
操作二:
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`然後重新執行上面兩個mysql客戶端工具的操作,執行到第二步的時候命令列還是無法刪除,但是如果刪除其他資料卻是可以的add index `order_date` (`order_date` asc) ;
說明innodb在加了索引的的行上加鎖是加的行級鎖,而且是對索引加的鎖
今天又做了一些測試,再次總結一下:
比如:
delimiter $$執行:set autocommit=0;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$$
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 對索引項之間的 間隙 第一條記錄前的 間隙 或者最後一條記錄後的...